Jersey容器请求过滤器 - 修改查询参数不会修改控制器中的上下文请求

3

我在Tomcat 7.0.69上运行Jersey 2.23,具有以下过滤器:

@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());
    }
}

这个过滤器会将查询参数“a”的值替换为“c”的值。

控制器如下:

@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);
    ...
}

我随后发出一个请求:http://localhost:8080/PathToController?a=b

我期望的输出结果是:

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

然而,输出结果为:
Context query string: a=b
Query param value: c

因此,我的过滤器修改了使用@QueryParam解析的查询参数,但它没有改变注入的上下文。预匹配过滤器不应该也修改注入的上下文吗?

1个回答

0

在Servlet层,HttpServletRequest不会被Jersey修改。请求的修改仍然在Jersey中进行。如果您使用了JAX-RS特定的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);
    ...
}

你会看到查询参数值按预期更改。

如果您认为此行为违反了JAX-RS规范,您应该在https://java.net/jira/browse/JERSEY/上提交错误报告。

如果您需要修改HttpServletRequest对象,则可能会发现Michal在SO上的答案有用:https://dev59.com/W3XYa4cB1Zd3GeqP_N-c#18331401


感谢您的回答。确实,注入的UriInfo对象具有修改后的查询参数。但是,我没有看到在过滤器中修改HttpServletRequest对象的方法。我可以使用setProperty(),但似乎只是在请求上设置属性。ThreadLocal<HttpServletRequest>注入不起作用。我想在jersey项目中提交一个票据,但似乎我需要创建一个帐户,目前这是不可能的。有什么想法可以提交这个票吗? - user1390217
抱歉造成困惑。ThreadLocal<HttpServletRequest> 只有在过滤器是单例的情况下才有用,而且似乎在 Jersey 2.x 中不受支持。无论如何,修改 HttpServletRequest 确实很复杂,特别是如果没有标准 API 的话。请查看这个答案,它可能会对你有所帮助:https://dev59.com/VnNA5IYBdhLWcg3wn_Q1 - Stepan Vavra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接