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

  • 相关阅读:
    Why is exponentiation applied right to left? Python
    What do these operators mean (** , ^ , %, //)? [closed] Python
    Difference between npm and yarn
    could not find a part GeneratedMSBuildEditorConfig.editorconfig
    git checkout b 本地分支 origin/远程分支 规格严格
    Instant Gratification with Flowable Open Source 规格严格
    【Linux】Linux中在mate桌面和gnome桌面root自动登录设置 规格严格
    Centos7修改网卡名字方法 规格严格
    Flowable的基本操作 规格严格
    SpringBoot+flowable实现工作流 规格严格
  • 原文地址:https://www.cnblogs.com/zjc-cnblogs/p/7302635.html
Copyright © 2020-2023  润新知