3

I have the following filter in jersey 2.23 running in tomcat 7.0.69:

@PreMatching
@Priority(Priorities.HEADER_DECORATOR)
public class TestFilter implements ContainerRequestFilter {
    @Context
    HttpServletRequest req;

    @Override
    public void filter(ContainerRequestContext conReqCtx) throws IOException {
        UriBuilder b = conReqCtx.getUriInfo().getRequestUriBuilder();
        b.replaceQueryParam("a", "c");
        conReqCtx.setRequestUri(b.build());
    }
}

The filter replaces the value of the query param "a" with the value "c".

The controller looks like:

@Context
HttpServletRequest req;

@GET
@Path("/PathToController")
public Response get(@QueryParam("a") String val) {
    System.out.println("Context query string: " + req.getQueryString());
    System.out.println("Query param value:" + val);
    ...
}

I then make a request: http://localhost:8080/PathToController?a=b

I expect the output to be:

Context query string: a=c
Query param value: c

However, the output is:

Context query string: a=b
Query param value: c

So my filter modified the query param that is parsed using @QueryParam, but it is not changing the injected context. Shouldn't the injected context also be modified by a PreMatching filter?

Stepan Vavra
  • 3,884
  • 5
  • 29
  • 40
user1390217
  • 41
  • 1
  • 5

1 Answers1

0

The servlet layer, the HttpServletRequest does not get modified by Jersey. The modification to the request remains in Jersey. If you used JAX-RS specific UriInfo:

@Context
private UriInfo uriInfo;

@GET
@Path("/PathToController")
public Response get(@QueryParam("a") String val) {
    System.out.println("Context query string: " + uriInfo.getQueryParameters());
    System.out.println("Query param value:" + val);
    ...
}

you would see that the query param value is changed as expected.

If you think this behavior violates JAX-RS spec you should submit a bug at https://java.net/jira/browse/JERSEY/

In case you need to modify the HttpServletRequest object you might find useful Michal's answer at SO: https://stackoverflow.com/a/18331401/3114959

Community
  • 1
  • 1
Stepan Vavra
  • 3,884
  • 5
  • 29
  • 40
  • Thanks for your answer. Indeed the injected UriInfo object has the modified query param. However,I do not see a way to modify the HttpServletRequest object in the filter. I can use setProperty() but that seems to be just setting an attribute on the request. ThreadLocal injection is not working. I would like to submit a ticket in the jersey project, however it seems like I need to create an account, which is currently not possible. Any ideas on how to submit the ticket? – user1390217 May 27 '16 at 13:41
  • Sorry for the confusion. `ThreadLocal` is useful only if a filter was a singleton and it seems to not be supported in Jersey 2.x. Anyway, modifying `HttpServletRequest` is indeed complicated, especially if there is no standard API for it. Check out this answer which might help you out: http://stackoverflow.com/questions/892537/how-to-set-a-parameter-in-a-httpservletrequest – Stepan Vavra May 27 '16 at 13:59