ContainerResponseFilter运行两次,标头未修改

时间:2017-09-14 10:42:30

标签: java filter jersey jetty servlet-filters

过滤器拦截所有请求,并为响应添加自定义标头。

当我实现ContainerResponseFilter时,filter方法运行两次:

@Provider
public class MyCustomFilter implements ContainerResponseFilter throws IOException {

   @Override
   public void filter(ContainerRequestContext containerRequestContext, 
    ContainerResponseContext containerResponseContext) {
       containerResponseContext.getHeaders().add("My-Key", "myvalue");
    }

}

并且,提供给客户端的响应包含标题。

我已经尝试调试Jetty和Jersey配置,并将问题缩小到以下我无法修改的旧版控制器逻辑:

        OutputStream out = response.getOutputStream();
        PrintWriter printout = new PrintWriter(out);
        JSONObject obj = new JSONObject(dummyData);
        printout.print(obj);

似乎直接写入响应流会触发一些JAX-RS生命周期链,从而导致额外的处理阶段。

我在Jersey 2.52.1和Jetty 9.4.4上。

1 个答案:

答案 0 :(得分:0)

解决了它。

似乎访问outputstream并执行printwriter.print()会触发HttpServletResponse“WRITE”状态并开始将响应返回给客户端。

所以在我的控制器中:

@GET
@Path("/seatemperatures")
public HttpServletResponse modifyResponse(@Context HttpServletRequest request, @Context HttpServletResponse response) {
    UtilClass.workOnResponse(request, response); //this uses printwriter.write()
    return response;
}

我必须将返回类型更改为void:

@GET
@Path("/seatemperatures")
public void modifyResponse(@Context HttpServletRequest request, @Context HttpServletResponse response) {
    UtilClass.workOnResponse(request, response);
}

从控制器返回响应对象似乎导致内部500错误并有效地尝试返回两个响应对象。