使用ContentCachingResponseWrapper丢失标题

时间:2018-07-23 16:42:27

标签: spring-mvc spring-boot servlets interceptor

我必须记录响应正文和响应标头。为此,我使用了Interceptor和ContentCachingResponseWrapper类(我也尝试使用过滤器,但结果相同)。当我将两者结合时,会丢失一些标头信息,但如果仅使用Interceptor,则不会丢失。

我的dispatcherServlet:

@Component("dispatcherServlet")
public class MyDisPatcherServlet extends DispatcherServlet {
    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            super.doDispatch(request, new ContentCachingResponseWrapper(response));
        } catch (Exception e) {
            super.doDispatch(request,response);
        }
    }
}

当我在拦截器的postHandle中使用ContentCachingResponseWrapper时:

private Map<String, List<Object>> getHeaders(HttpServletResponse response){
    Map<String, List<Object>> headersList = new HashMap<>();
    Collection<String> headerNames = ((ContentCachingResponseWrapper)response).getHeaderNames();
    // Same if I use response.getHeaderNames()
    if (headerNames != null) {
        for(String headerName : headerNames){
            headersList.put(headerName, Arrays.asList(response.getHeaders(headerName))); 
        }
    }
    return headersList;
}

标题结果:

  

{Set-Cookie = [[JSESSIONID = 109DE678B86611DE627B9B7B3B513DEF;   路径= /服务/服务; HttpOnly]]}


如果我取消激活MyDisPatcherServlet组件,并直接从响应中读取标头名称:

private Map<String, List<Object>> getHeaders(HttpServletResponse response){
    Map<String, List<Object>> headersList = new HashMap<>();
    Collection<String> headerNames = response.getHeaderNames();
    if (headerNames != null) {
        for(String headerName : headerNames){
            headersList.put(headerName, Arrays.asList(response.getHeaders(headerName))); 
        }
    }
    return headersList;
}

标题结果:

  

{X-Frame-Options = [[DENY]],Transfer-Encoding = [[chunked]],   Cache-Control = [[[no-cache,no-store,max-age = 0,必须重新验证]],   X-Content-Type-Options = [[nosniff]],Connection = [[close]],   Set-Cookie = [[JSESSIONID = 9E2F642595202D87935F4CD5C089ADFE;   路径= /服务/服务; HttpOnly]],Pragma = [[no-cache]],   过期时间= [[0]],X-XSS-Protection = [[1;模式=块]],日期= [[7月23日星期一   2018 16:15:55 GMT]],Content-Type = [[application / json; charset = UTF-8]]}

谢谢。

1 个答案:

答案 0 :(得分:0)

您必须先致电copyBodyToResponse(),然后才能获取标头。