拦截器配置
1 <mvc:interceptors> 2 <mvc:interceptor> 3 <mvc:mapping path="/luxury/**" /> 4 <bean class="com.web.intercepter.ReqContextInterceptor" /> 5 </mvc:interceptor> 6 <!-- <mvc:interceptor> 7 <mvc:mapping path="/laundry/**" /> 8 <bean class="com.web.intercepter.ReqContextInterceptor" /> 9 </mvc:interceptor> --> 10 </mvc:interceptors>
拦截器代码
1 /** 2 * 拦截器--记录当前请求的request/reponse 3 * 4 * @author zhujunchao 5 */ 6 public class ReqContextInterceptor extends HandlerInterceptorAdapter { 7 8 @Override 9 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 10 // 统一处理逻辑 11 RequestResponseContext.setRequestAndResponse(request,response); 12 return true; 13 } 14 15 @Override 16 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 17 ModelAndView modelAndView) throws Exception { 18 //不处理 19 } 20 21 @Override 22 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 23 throws Exception { 24 } 25 }
RequestResponseContext代码
1 /** 2 * 存放当前请求的request、response 3 */ 4 public class RequestResponseContext { 5 private static ThreadLocal<HttpServletRequest> request_threadLocal = new ThreadLocal<HttpServletRequest>(); 6 7 private static ThreadLocal<HttpServletResponse> reponse_threadLocal = new ThreadLocal<HttpServletResponse>(); 8 9 private RequestResponseContext() {} 10 11 public static void setRequestAndResponse(HttpServletRequest request,HttpServletResponse response) { 12 request_threadLocal.set(request); 13 reponse_threadLocal.set(response); 14 } 15 16 public static void clearRequestAndResponse() { 17 request_threadLocal.remove(); 18 reponse_threadLocal.remove(); 19 } 20 21 public static HttpServletRequest getRequest() { 22 return request_threadLocal.get(); 23 } 24 25 public static HttpServletResponse getResponse() { 26 return reponse_threadLocal.get(); 27 } 28 }
页面1:/luxury/index?serviceCode=8002
1 @RequestMapping(value = "/luxury/index") 2 public String goodsList(IndexRequestVo reqVo) { 3 RequestResponseContext.getResponse().addCookie("serviceCode", String.valueOf(serviceCode)); 4 return "/luxury/index"; 5 }
页面2:/laundry/index?serviceCode=8001
1 @RequestMapping(value = "/laundry/index") 2 public String goodsList(IndexRequestVo reqVo) { 3 RequestResponseContext.getResponse().addCookie("serviceCode", String.valueOf(serviceCode)); 4 return "/laundry/index"; 5 }
因为没有对:/laundry 进行拦截,出现了
请求1:/laundry/index?serviceCode=8001...
请求2:访问/luxury/index?serviceCode=8002 查看cookie的serviceCode值为8001(应该为8002)
原因:
1.请求1: ReqContextInterceptor 没有对 /laundry/* 进行拦截,即没有在RequestResponseContext(ThreadLocal)中 存放当前请求的request、response
2.请求1: 在调用RequestResponseContext.getResponse() 实际上获取的是由/luxury/*请求放入的response-->因为处理请求使用的是线程池里获取的线程
这时 response实际上是/luxury/*请求的response
3.请求1:调用response.addCookie,写值 serviceCode=8001
流程:
1. /luxury/index?serviceCode=8002 请求,将response放入ThreadLocal中,写入cookie(serviceCode=8002)======>请求结束
2. /laundry/index?serviceCode=8001 请求,因为没有写ThreadLocal 且同(1) 用的是同一个现成 从ThreadLocal中获取到(1)中的response
写入cookie(serviceCode=8001)======>请求结束
猜测两种情况:
1》请求(2)写请求(1) 的response 导致请求(1)看到的cookie值改变
2》请求(3)请求(1) 重新刷新页面 -->(新的response,新的线程),因为请求(2)的response和请求(3)的response 指向同一个用户、页面,请求(2)的response后执行addCookie(serviceCode=8001),导致请求(1)或(3)最终看的的是cookie(serviceCode=8001)
具体需要研究response 和socket io流 这块还不熟。。。。。。