在一次http会话中,线程内变量的存储依赖于HttpSession,而实际应用中有很多地方是无法取到HttpSession的,那么怎么样才能灵活的获取线程内变量?其实很简单只需要定义静态的变量,并在动作执行前进入将线程变量保存到静态变量中即可,那么在本次HTTP会话中需要用到线程变量的地方只需要调用静态变量并获取对应的值就可以了
以下是存储和获取线程内变量的类源码UserSession,可以保存线程内的相关变量,例如用户的名,昵称等相关的信息
public class UserSession {
//线程变量,注意new的一定是个Hashtable而不是HashMap
private static final ThreadLocal<Map> sessionMap = new ThreadLocal<Map>(){
protected Map initialValue() {return new Hashtable();}
};
/**
* 取得属性
* @param attribute
* @return
*/
public static Object get(String attribute) {
Map map = sessionMap.get();
return map.get(attribute);
}
/**
* 取得属性
* @param <T>
* @param attribute
* @param clazz
* @return
*/
public static <T> T get(String attribute, Class<T> clazz) {
return (T) get(attribute);
}
/**
* 设置属性
* @param attribute
* @param value
*/
public static void set(String attribute, Object value) {
Map map = sessionMap.get();
map.put(attribute, value);
}
}
以上只是提供了一个类去保存变量,在HTTP会话中,我们应该是动作开始前去注入变量并保存,这里就要用到filter,在web.xml中添加一个filter
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>com.jteap.core.web.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
在定义的OpenSessionInViewFilter中我们重写方法doFilterInternal()
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//设置当前用户到线程变量
setLocalVar((HttpServletRequest)request,(HttpServletResponse)response);
super.doFilterInternal(request, response, filterChain);
}
/**
* 设置本地线程变量
* @param request
* @param response
*/
private void setLocalVar(HttpServletRequest request, HttpServletResponse response){
UserSession.set(Constants.THREADLOCAL_CURRENT_SESSION, request.getSession());
}
以上在动作前就设置好了相关线程变量,那么在http后任何需要变量的地方只需要UserSession.get(attribute)就可以获取对应变量的值了
例如在aop编程中完成日志的记录功能,在用户进行动作完成后使用AOP编程来进入对应的方法,这里需要用户的相关信息可是却无法获取HTTPSESSION了,这时候UserSession的作用就体现出来了。