shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.walker.web;
 
import com.walker.infrastructure.core.NamedThreadLocal;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * 可获得请求对象的上下文环境</p>
 * 通过线程绑定<code>HttpServletRequest</code>让<code>Action</code>层获得请求支持。
 * @author shikeying
 * @date 2013-10-1
 *
 */
public abstract class RequestAwareContext {
    
    /* 因为界面中用户可能频繁恶意刷新,因此在tomcat等中间件中,会存在多个请求
     * 重复使用线程池中的某个线程,造成重复绑定。
     * 所以设置此参数,控制是否允许重复绑定,同时后续还要解决重复提交的问题。
     * 2014-6-30 时克英 */
//    private static boolean requestOverride = false;
 
    private static boolean requestOverride = true;
 
    public static boolean isRequestOverride() {
        return requestOverride;
    }
 
    /**
     * 是否允许线程局部变量的覆盖,默认不允许。</br>
     * 注意:在系统中该方法只能被调用一次,即:初始化调用。
     * @param requestOverride
     */
    public static void setRequestOverride(boolean requestOverride) {
        RequestAwareContext.requestOverride = requestOverride;
    }
 
    private static final NamedThreadLocal<HttpServletRequest> requestLocals
        = new NamedThreadLocal<HttpServletRequest>("walker_request_threadlocal");
    
    private static final NamedThreadLocal<HttpServletResponse> responseLocals
    = new NamedThreadLocal<HttpServletResponse>("walker_response_threadlocal");
    
    /**
     * 设置当前线程绑定的请求对象<code>HttpServletRequest</code>。<br>
     * 当前某些环境会出现恶意刷新界面时,tomcat线程池重复绑定的情况,可以通过捕获异常提示用户。
     * @throws BindRequestRepeatException 当不允许重复绑定线程变量时,出现重复绑定会抛出异常
     * @param request
     */
    public static void setCurrentRequest(HttpServletRequest request){
        HttpServletRequest _r = requestLocals.get();
        if(_r != null){
            if(!isRequestOverride())
                throw new BindRequestRepeatException("request can't be binded repeatly! request = " + _r);
            else {
                // 如果允许覆盖
                requestLocals.remove();
            }
        }
        requestLocals.set(request);
    }
    
    public static HttpServletRequest getCurrentRequest(){
        return requestLocals.get();
    }
    
    public static void clearCurrentRequest(){
        requestLocals.remove();
    }
    
    public static void setCurrentResponse(HttpServletResponse response){
        HttpServletResponse _r = responseLocals.get();
        if(_r != null)
            throw new IllegalStateException("response can't be binded repeatly! response = " + _r);
        responseLocals.set(response);
    }
    
    public static HttpServletResponse getCurrentResponse(){
        return responseLocals.get();
    }
    
    public static void clearCurrentResponse(){
        responseLocals.remove();
    }
    
    public static class BindRequestRepeatException extends IllegalStateException{
        /**
         *
         */
        private static final long serialVersionUID = -7221718348573512540L;
 
        public BindRequestRepeatException(){
            super("request can't be binded repeatly!");
        }
 
        public BindRequestRepeatException(String msg){
            super(msg);
        }
 
        public BindRequestRepeatException(String msg, Throwable cause){
            super(msg, cause);
        }
    }
}