【问题标题】:How to store retrieved object in session and access it afterwords?如何在会话中存储检索对象并在之后访问它?
【发布时间】:2016-02-02 14:01:04
【问题描述】:

我正在尝试创建一个简单的登录页面。我使用休眠从我的数据库中检索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,所以请多多包涵。

【问题讨论】:

    标签: java hibernate jakarta-ee


    【解决方案1】:

    您可以使用可由 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

    【讨论】:

    • 非常感谢您提供这个简单的答案,我是 hibernate 的新手,为了擅长它,我正在使用 hibernate 创建一个带有 maven 的电子商务网络应用程序,并在最后 8 个中寻找它-9 小时,我遇到了很多解释和视频,但这是我一直在寻找的最简单和准确的路线。非常感谢。
    【解决方案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 在这里可能会有所帮助。

    【讨论】:

    • 非常感谢您提供的有用提示。我希望我能接受两个答案。
    【解决方案3】:

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

    以下是你将如何做到这一点:

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

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

    httpSession.getAttribute("loggedUser");//return type is Object here
    

    【讨论】:

      【解决方案4】:

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

      建议

      • 您不应该回滚 get/select 操作吗?
      • SessionFactory 应该被实例化一次。

      【讨论】:

        猜你喜欢
        • 2019-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多