26

HttpServletRequest has a method setAttribute(String, Object).

How can I extract this attribute from ContainterRequest?

I didn't find: getAttribute method!

Code

public class AuthenticationFilter implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) servletRequest;
        // .... ....
        httpReq.setAttribute("businessId", businessId);
    }
}

In Jersey Filter:

private class Filter implements ResourceFilter, ContainerRequestFilter {
    public ContainerRequest filter(ContainerRequest request) {
        // ..extract the attribute from the httpReq
    }
}
Steven Benitez
  • 10,936
  • 3
  • 39
  • 50
Dejell
  • 13,947
  • 40
  • 146
  • 229

4 Answers4

48

You can't. They're not exposed through the Jersey API in any way. If you search the Jersey codebase, you'll find that there are no uses of HttpServletRequest.getAttributeNames(), which you'd expect to be used if they were being copied en masse. You'll also find that there are only a handful of uses of HttpServletRequest.getAttribute(), and it's strictly for internal bookkeeping.

Note, however, that when deployed in a Servlet Context, JAX-RS allows you to inject the original HttpServletRequest using the @Context annotation. I'm not certain whether you can do this in a Jersey filter, but it works in MessageBodyReaders/Writers and in resource classes.

Update: I've checked, and you can, in fact, inject the HttpServletRequest into a Jersey ContainerRequestFilter by simply including:

@Context private HttpServletRequest httpRequest;
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • Can I inject it in Jersey Filter? – Dejell Jun 09 '13 at 13:41
  • So why Jersey not simple extends HttpServletRequest? – Dejell Jun 09 '13 at 15:29
  • 1
    You'd have to ask the Jersey developers that. For my part, I'm glad they didn't. I find ContainerRequest a lot more useful than HttpServletRequest. – Ryan Stewart Jun 09 '13 at 21:51
  • Where did you find it more useful? In which case? Why couldn't they add the parameters of HttpServletRequest? (just to extend it) – Dejell Jun 10 '13 at 07:51
  • 1
    Parameters are not attributes. In my experience and opinion, request attributes are mostly useful to framework designers and not app developers and request parameters are mostly the reverse. ContainerRequest is way more useful because it has methods for doing things with a request that you want to do in the context of a REST API, like getting path segments as a List, getting parameters as a multi-valued map, getting a UriBuilder to help with URI construction, and much more. – Ryan Stewart Jun 11 '13 at 00:31
  • I wanted to arrange the code better, so I took the ContainerRequestFilter out of the ResourceFilterFactory, but now httpServletRequest is null. Only when I put it in the ResourceFilterFactory it wasn't empty. Any idea why? – Dejell Jul 07 '13 at 06:17
  • The `@Context` annotation is part of the JAX-RS spec and is therefore only acted on when it's in a class Jersey is managing. You probably moved it out to some other class that you're creating yourself or through some other framework, like Spring. – Ryan Stewart Jul 08 '13 at 16:22
  • Correct, I moved it to the class that implements ResourceFilter. How can I tell Jersey to manage it? in web.xml I put on the class that implements ResourceFilterFactory – Dejell Jul 08 '13 at 17:41
  • By "manage", I mean Jersey is in charge of the lifecycle. That covers things like resource classes, filter factories, message body readers/writers, exception mappers, and generally any other `@Provider`. These are things the Jersey framework creates, destroys, and uses to service requests. If you need further clarification, I suggest you open a new question. – Ryan Stewart Jul 09 '13 at 13:48
  • I have problem in doing this .. The property are always null once I am inside the method public ContainerRequest filter(ContainerRequest request) .. I am using jersey 1.6 and I am on Google App Engine – Michele Orsi Aug 24 '13 at 00:48
  • @MicheleOrsi: You should post a new question describing your problem. – Ryan Stewart Aug 24 '13 at 00:53
  • I found a similar question to my needs: http://stackoverflow.com/questions/18157177/how-to-get-a-session-object-in-the-containerrequest-to-can-use-the-annotation-r – Michele Orsi Aug 24 '13 at 07:22
  • I couldn't get this to work with `ServletRequest` and Jersey 2.0-m11. Not sure if that is useful to anyone. It had to be `HttpServletRequest`. – Jayen Apr 26 '15 at 06:14
6

If you're using Jersey 2, which implements JAX-RS 2.0, you can implement a ContainerRequestFilter which defines a filter method as follows:

public void filter(ContainerRequestContext requestContext) throws IOException;

ContainerRequestContext has getProperty(String) and setProperty(String, Object) methods, which in a Servlet environment (ServletPropertiesDelegate), map to the servlet request's getAttribute(String) and setAttribute(String, Object) methods.

See: Jersey on GitHub

Steven Benitez
  • 10,936
  • 3
  • 39
  • 50
4

I got the @Context working, but have the problem is that my ContainerRequestFilter is singleton.

I had to implement a custom javax.servlet.Filter and use a ThreadLocal to store the HttpServletRequest.

huljas
  • 147
  • 1
  • 3
1

I wanted to add to previous answers my solution, in addition to adding context:

@Context
private HttpServletRequest httpRequest;

You should set and get attributes from the session.

Set:

 httpRequest.getSession().setAttribute("businessId", "yourId");

Get:

Object attribute = httpRequest.getSession().getAttribute("businessId");
Ari Bustamante
  • 84
  • 2
  • 11
Ori Marko
  • 56,308
  • 23
  • 131
  • 233