我有一个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作为我的容器/应用服务器。
答案 0 :(得分:3)
当响应点击postHandle
中的HandlerInterceptor
方法时,响应可能已经提交,这意味着您无法再写回复标头
这就是为什么大多数情况下这种行为是在Servlet过滤器中实现的,并使用缓存包装器包装响应。请参阅ShallowEtagHeaderFilter
及其在Spring中使用ContentCachingResponseWrapper
。