Spring MVC获取session的问题

java菜鸟一枚,问一个问题

一个管理系统 , 使用spring mvc 3.2 先描述一下我想实现的目标: 我想有一个类Member , 实现获取当前用户的SESSION , 调用方式想类似这样
1.new一个Member实例

Member m = new Member();
m.getId();
//或
m.id;

2.不用new , 直接获取

Member.getId(); 
//或
Member.id;

最早我这样写

        public class Member {
        @Autowired
        HttpSession session;
        public String getId() {
        return session.getAttribute("emp_id") != null ? session.getAttribute("emp_id").toString() : "";
        }
        private String id;
    }

其中@Autowired是根据 http://blog.csdn.net/yousite1/article/details/7108585 设置的 可是我在使用的时候

Member m = new Member();
String id = m.getId();

会报错 java.lang.NullPointerException 同时输出 session 为 null

后面我又改了一下 , 同样参考上面那个文章

        public class Member {
        public String getId() {
        HttpServletRequest session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        return session.getAttribute("emp_id") != null ? session.getAttribute("emp_id").toString() : "";
        }
        private String id;
    }

这样是能获取SESSION了...

我想知道
1.能不能实现 , 不使用 getId() , 直接使用 id 获取值?

Member m = new Member();
String id = m.id; //如果id为public

2.能不能实现静态变量获取SESSION值呢?
恩 , 比如我在C#下这么些

    public class  Member {
        private static String _id;
        public static String id{
            get { return (String)HttpContext.Current.Session["emp_id"];}
            set { Member.id = value; }
        }
    }

    String id = Member.id;

3.为什么使用注解@Autowired, 获取不到session值呢?
因为如果按我第二种写法, 每一字段都需要加获取sesssion的方法
如果有id , name , code ....需要写好多
有没有办法实现在一个地方写一次 , 其他地方直接获取?

4.第二种写法,我会在每个需要用到session的地方都加一个 , 而这个我是每个control中必须要用到的

Member m = new Member();
//然后再使用 m.getId()

所以,能不能实现在页面进入到controller前,能有个地方设置一个全局变量 , 然后我直接在controller中使用呢,比如 m.getId() , m为已经设置过的全局变量
其实我上面第二个问题中用static就是想实现这样 , 图省事

恩,知识太浅,很多地方都不知道如何实现,或者能不能那样实现...
求助大家,谢谢...

阅读 38.7k
4 个回答

我也觉得楼主这样写有点乱,Member应该算Model层的代码吧,怎么能直接和session打交道,这个工作应该交给controller层吧。而且你说你想使用static字段来存储在session中,问题是一个tomcat容器里(假设你不是用cluster)应该只有一个static字段的实例(如果我没有猜错一个tomcat应该对一个JVM),你让每个连接的用户对应的所有session怎么去共享这个字段。一般的写法都不是像楼主这么写的。

简单回答:

  1. 可以实现不使用 “ getId() , 直接使用 id 获取值 ”,不过这样一来没有什么意义,且有违OO的设计原则;
  2. 不能实现静态变量获取,因为静态变量是类级别共享,而session是会话级别共享,两个的作用域范围不同;
  3. @Autowired无法注入Session,就算自己另想其他的办法注入到类中也是不对的,原因同2,对象级别和会话级别的作用域范围不同;
  4. 不需要像你所说的那样用,一般是把需要共享的数据组合成类如Member,包含id,name,code等,然后把整个Member放到session中,在具体需要的地方再取用;

PS:首先要理解什么是Session, Session是为了保持一次会话中多个交互过程共享某些数据而在服务器端开辟出来的一个数据存储区,实际上其实就是Map,只不过这个Map跟标识一次会话的会话Id(jsessionId,你经常在浏览器的cookies中可以看到)绑定。而一般session都是从每次请求的HttpServletRequest中获取的,所以对于每次请求,你当然需要从里面获取session数据或者设置session数据,就跟Map的get和put操作类似。所以建议尝试以下用法:

// 在每个controller的方法中
HttpSession session = getHttpSession(request);   // 这个方法一般放在父类的Controller中
session.get("xxx");
session.set("xxx", val);
新手上路,请多包涵

你可以在Controller里面获取需要的Session里面的值,你的Member是MVC里面的model层面的,而Session是controller里面的,怎么关联,楼上的设置是正确的,可以通过public String index(Model model,HttpServletRequest request,HttpSession session)进行获得

新手上路,请多包涵

我懂楼主想干什么,因为我也遇到了相同的问题,
就是session里面有个变量,楼主需要取出来传到后面的业务逻辑里面去用,但不想每次都手动从session里面去取这个 变量。例如:

@RequestMapping(value = "/patrol/countPatrolUser")
@ResponseBody
public int countPatrolUser(HttpSession session, UserQueryVo userQueryVo) {
    // 获取sessionInfo
    SessionInfo sessionInfo = (SessionInfo) session.getAttribute(GlobalConstant.SESSION_INFO);
    // 设置当前用户的qybm
    userQueryVo.setUserQybm(sessionInfo.getCaseXzqh().getCode());
    int result = 0;
    result = userService.countPatrolUser(userQueryVo);
    return result;
}

这里的userQueryVo是从前端传过来的,有没有什么方法在 userQueryVo new 出来的时候就从session里面把qybm取出来设置好!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏