Spring MVC 4:拦截器无法设置Response头

时间:2015-07-10 14:10:05

标签: java spring spring-mvc jboss wildfly

我有一个Spring 4 MVC应用程序,其中有一个拦截器,用于计算请求响应周期的执行时间,我想设置一个像X-Runtime这样的标头,其中包含执行时间的值。但是,response.setHeader功能无效。当响应到达我的浏览器时,它被覆盖了。

我有一个CORS过滤器,我在其中设置请求和响应标头以启用跨源请求,并且工作正常。

这是我的拦截器:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class ExecuteTimeInterceptor extends HandlerInterceptorAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExecuteTimeInterceptor.class.getName());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        LOGGER.info("Request URL::" + request.getRequestURL().toString() + ":: Start Time=" + System.currentTimeMillis());
        request.setAttribute("startTime", startTime);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        Long startTime = (Long) request.getAttribute("startTime");
        Long timeTaken = (System.currentTimeMillis() - startTime);
        LOGGER.info("Request URL::" + request.getRequestURL().toString() + ":: Time Taken=" + timeTaken);
        response.setHeader("X-Runtime", timeTaken.toString());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // Do nothing.
    }
}

我已在dispatcher.xml配置文件中正确配置了拦截器。 slf4j正确记录执行时间,因此我可以确认拦截器本身是否正常工作。

知道为什么会这样吗?我使用WildFly(以前的JBoss)8.1作为我的容器/应用服务器。

1 个答案:

答案 0 :(得分:3)

当响应点击postHandle中的HandlerInterceptor方法时,响应可能已经提交,这意味着您无法再写回复标头

这就是为什么大多数情况下这种行为是在Servlet过滤器中实现的,并使用缓存包装器包装响应。请参阅ShallowEtagHeaderFilter及其在Spring中使用ContentCachingResponseWrapper