关键字: 线程变量的保存 在一次http会话中,线程内变量的存储依赖于HttpSession,而实际应用中有很多地方是无法取到HttpSession的,那么怎么样才能灵活 的获取线程内变量?其实很简单只需要定义静态的变量,并在动作执行前进入将线程变量保存到静态变量中即可,那么在本次HTTP会话中需要用到线程变量的地 方只需要调用静态变量并获取对应的值就可以了
以下是存储和获取线程内变量的类源码UserSession,可以保存线程内的相关变量,例如用户的名,昵称等相关的信息
- public class UserSession {
-
- private static final ThreadLocal<Map> sessionMap = new ThreadLocal<Map>(){
- protected Map initialValue() {return new Hashtable();}
- };
-
-
-
-
-
-
- public static Object get(String attribute) {
- Map map = sessionMap.get();
- return map.get(attribute);
- }
-
-
-
-
-
-
-
-
- public static <T> T get(String attribute, Class<T> clazz) {
- return (T) get(attribute);
- }
-
-
-
-
-
-
- public static void set(String attribute, Object value) {
- Map map = sessionMap.get();
- map.put(attribute, value);
- }
- }
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>
<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);
- }
-
-
-
-
-
- private void setLocalVar(HttpServletRequest request, HttpServletResponse response){
- UserSession.set(Constants.THREADLOCAL_CURRENT_SESSION, request.getSession());
- }
@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的作用就体现出来了。