如何在Service层获取用户session中保存的用户信息的方法

这是我在网上找到的一段保存UserSession的java代码。
[code="java"]

/**

  • Description: 用ThreadLocal提供一个存储线程内变量的地方.

  • 客户端代码可以用静态方法存储和获取线程内变量,不需要依赖于HttpSession.
  • web层的Controller可通过此处向business层传入user_id之类的变量
  • /
    @SuppressWarnings("unchecked")
    public class UserSession {
    /
    * * 保存变量的ThreadLocal,保持在同一线程中同步数据. */
    private static final ThreadLocal SESSION_MAP = new ThreadLocal();

    /** * 工具类的protected构造方法. */
    protected UserSession() {
    }

    /**

    • 获得线程中保存的属性.
    • @param attribute
    • 属性名称
    • @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);
      }

    /**

    • 获得线程中保存的属性,使用指定类型进行转型.
    • @param attribute
    • 属性名称
    • @param clazz
    • 类型
    • @param
    • 自动转型
    • @return 属性值 */ public static T get(String attribute, Class clazz) { return (T) get(attribute); }

    /**

    • 设置制定属性名的值.
    • @param attribute
    • 属性名称
    • @param value
    •        属性值
      

      */
      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的误用。