在过滤器中添加响应标头?

我需要在每个响应中添加标头。我打算在下面做

public class MyFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        filterChain.doFilter(request, response);
            response.addHeader("Access-Control-Allow-Origin", "*"); 
    }

}

我想在之后这样做,以便一旦控制器处理它,我就在返回客户端之前添加标头。它是正确的吗?filterChain.doFilter(request, response)

但是按照如何编写响应过滤器?

返回后,对响应执行任何操作都为时已晚。此时,整个响应已发送到客户端,您的代码无权访问它。chain.doFilter

上述说法在我看来不对。我不能在后面添加标题吗?如果不是为什么?filterChain.doFilter(request, response)

我正在使用弹簧mvc。


答案 1

在被调用后,对响应做任何事情都为时已晚。此时,整个响应已发送到客户端。filterChain.doFilter

您需要将包装响应构建到自己的类中,将这些包装器传递到方法中,并处理包装器中的任何处理。doFilter

已经有一个响应包装器:您可以扩展它。例如:HttpServletResponseWrapper

public class MyResponseRequestWrapper extends HttpServletResponseWrapper{
    public MyResponseRequestWrapper(HttpServletResponse response) {
        super(response);
    }
}

您的过滤器:

@Override
protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

    HttpServletResponse myResponse = (HttpServletResponse) response;
    MyResponseRequestWrapper responseWrapper = new MyResponseRequestWrapper(myResponse);
    responseWrapper.addHeader("Access-Control-Allow-Origin", "*");
    filterChain.doFilter(request, myResponse);
}

答案 2

我在 Spring 3.0.x 的项目中使用它:

public class MyFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException
    {
        response.addHeader("headerName", "headerValue");
        filterChain.doFilter(request, response);
    }
}

工作正常。


推荐