tomcat问题记录-线程池引发的问题

拦截器配置

 

 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流  这块还不熟。。。。。。

 

posted @ 2017-08-08 01:05  zjc@bj  阅读(461)  评论(0)    收藏  举报