package com.walker.web;
import com.walker.infrastructure.core.NamedThreadLocal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 可获得请求对象的上下文环境
* 通过线程绑定HttpServletRequest
让Action
层获得请求支持。
* @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;
}
/**
* 是否允许线程局部变量的覆盖,默认不允许。
* 注意:在系统中该方法只能被调用一次,即:初始化调用。
* @param requestOverride
*/
public static void setRequestOverride(boolean requestOverride) {
RequestAwareContext.requestOverride = requestOverride;
}
private static final NamedThreadLocal requestLocals
= new NamedThreadLocal("walker_request_threadlocal");
private static final NamedThreadLocal responseLocals
= new NamedThreadLocal("walker_response_threadlocal");
/**
* 设置当前线程绑定的请求对象HttpServletRequest
。
* 当前某些环境会出现恶意刷新界面时,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);
}
}
}