这是我在网上找到的一段保存UserSession的java代码。
[code="java"]
/**
/
@SuppressWarnings("unchecked")
public class UserSession {
/* * 保存变量的ThreadLocal,保持在同一线程中同步数据. */
private static final ThreadLocal SESSION_MAP = new ThreadLocal();
/** * 工具类的protected构造方法. */
protected UserSession() {
}
/**
@return 属性值
*/
public static Object get(String attribute) {
Map map = (Map) SESSION_MAP.get();
System.out.println(map.toString());
System.out.println(map.containsKey("usersession"));
return map.get(attribute);
}
/**
/**
属性值
*/
public static void set(String attribute, Object value) {
Map map = (Map) SESSION_MAP.get();
if (map == null) {
map = new HashMap();
SESSION_MAP.set(map);
}
map.put(attribute, value);
}
}
[/code]
我在用户登录的时候 执行:
[code="java"]
UserSession.set("User",User);
[/code]
然后在我需要的service层中执行
[code="java"]
UserSession.get("User");
//UserSession.get("User",User.class);
[/code]
这样第一次一般都取不到session中的User对象。
第二次就可以。请问这个是什么原因呢?
ThreadLocal 是当前请求的对象。每一次线程请求的时候,都需要从session中把session对象取出来。放到ThreadLocal中去。 这样才能从service中取得到。acegi就是这么处理的
看起来好像没什么问题,你打断点去看看
楼主是否想在各个层都能获取到当前客户端请求用户的session相关信息?如果是的话你的整个方案本身就是[color=red][b]存在问题[/b][/color]的。客户端请求的session与服务端的线程没有对应关系,即使你获取到了threadlocal中session信息只能说明你获取到了该线程中session信息,不一定就是当前客户端请求的session信息。之前一个老系统中审计日志就是使用的楼主描述的这种方法,某一次发现这样使用存在问题,经验证果然存在问题,现已从项目中去除,我觉得这是一个threadlocal的误用。