如何在会话中存储检索到的对象并在之后访问它?

时间:2015-11-02 16:02:44

标签: java hibernate java-ee

我正在尝试创建一个简单的登录页面。我使用hibernate从我的数据库中检索User对象。那部分工作正常,我这样做如下:

//data from login form
String username = request.getParameter("username").trim();
String password = request.getParameter("password").trim();

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
try {
    User currentUser = (User) session.get(User.class, username);
    if(password.equals(currentUser.getPassword())) {
        response.sendRedirect("index.jsp?page=login&success=true");
    } else {
        session.getTransaction().rollback();
        response.sendRedirect("index.jsp?page=login&success=false");
    }
} catch //...

如果凭据正确,登录成功。如果我理解正确,上面的代码已经将用户存储在会话中,如果登录成功,那么我所要做的就是访问会话了吗?

但是我无法弄清楚如何从我网站其他地方的会话中访问检索到的User对象。用户登录后,我想在我的网站上显示用户特定信息,为此,我需要检查用户名以及用户是否已登录。

总结一下:如何在网站的其他部分使用检索到的User对象?

我刚开始学习Java EE和hibernate,所以请耐心等待。

4 个答案:

答案 0 :(得分:3)

您可以使用可由HttpServletRequest对象检索的HttpSession来完成此操作。

HttpSession httpSession = request.getSession();
httpSession.setAttribute("user", user);

现在,要检查用户对象是否存在于应用程序的不同部分,您可以执行以下操作:

HttpSession httpSession = request.getSession(false); 
//False because we do not want it to create a new session if it does not exist.
User user = null;
if(httpSession != null){
    user = (User) httpSession.getAttribute("user");
}

if(user!=null){
    // Do stuff here
}

要注销用户或换句话说,要使会话无效,您可以调用invalidate方法。

httpSession.invalidate();

有用的链接:HttpServletRequestHttpSession

答案 1 :(得分:2)

HttpSession与Hibernate会话不同。 Hibernate会话为您提供了一种查询和保存存储在数据库中的持久实体的方法。 HttpSession由servlet容器提供,以提供方法 根据用户请求中提供的cookie为给定用户存储对象。

您在HttpSession中存储的内容应该是最小的,部分是为了节省集群中节点协调其会话的开销,但主要是为了使您的应用程序不易出错。这里,在会话中存储用户ID而不是整个用户对象就足够了。即使User对象包含角色,最好为每个请求查看这些角色,以便立即应用任何更改。此外,通过仅存储ID,可以避免重新附加实体的问题(允许您避免使用Hibernate时更令人困惑和麻烦的部分之一)。当您的应用程序中的其他内容需要访问用户时,它可以查询Hibernate会话(使用session.get(id))传递存储在HttpSession中的主键值。

您应该使用单向哈希来存储密码,这样就会改变您比较密码的方式。

应用程序应该只在初始化时创建一次Hibernate SessionFactory,它是线程安全的,应用程序中的所有内容都应该使用那个实例。

回滚一个事务,你所做的就是选择似乎没必要。

通常,您只能从视图和Web控制器访问HttpSession。看起来您将Web控制器逻辑和业务逻辑集中在一起,a division of responsibilities between controller and service在这里可能会有所帮助。

答案 2 :(得分:1)

您在此处提到的会话(org.hibernate.Session)无法从您网站的其他位置访问,而是将您的User对象放入 HttpSession

  

以下是你要做的事情:

//code.angularjs.org/1.3.0-rc.1/angular.min.js

//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css
  

以下是您从其他平台访问的方式:

HttpSession httpSession = request.getSession();
httpSession.setAttribute("loggedUser", your_user_object reference_here );

答案 3 :(得分:1)

假设您在Web应用程序中并且需要来自User实体的内容,则应将相同的值/引用传播到Web /控制器层(如果您使用的是MVC方法);然后保留它,因为它是通过大多数框架提供的HTTP会话存储内容的最合适的地方。

<强>建议(S)

  • 您不应该回滚获取/选择操作吗?
  • SessionFactory应该实例化一次。