java—在可能无效的会话上处理session.getattribute()的最佳实践

eoigrqb6  于 2021-10-10  发布在  Java
关注(0)|答案(0)|浏览(275)

我有一个会话侦听器:

  1. @WebListener
  2. public class SessionListener implements HttpSessionListener {
  3. @Override
  4. public void sessionCreated(HttpSessionEvent se) {
  5. Set<Integer> follows = ConcurrentHashMap.newKeySet();
  6. se.getSession().setAttribute("userFollows", follows);
  7. }
  8. }

我有一个loginservlet:

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. /* ... check parameters ... */
  4. try (Connection con = ConPool.getConnection()) {
  5. UserDAO service = new UserDAO(con);
  6. User user = service.get(username, true);
  7. if (user != null && user.getPassword().check(password) ) {
  8. HttpSession session = req.getSession(true);
  9. session.setAttribute("loggedUserId", user.getId());
  10. /* Adds guest's follows in db */
  11. Set<Integer> follows = (Set<Integer>) session.getAttribute("userFollows");
  12. if(!follows.isEmpty()) {
  13. FollowDAO followService = new FollowDAO(con);
  14. followService.insert(follows, user.getId());
  15. }
  16. resp.sendRedirect(req.getContextPath());
  17. } else {
  18. resp.sendError(400);
  19. return;
  20. }
  21. } catch (SQLException throwables) {
  22. throw new ServletException(throwables);
  23. }
  24. }

这是logoutservlet:

  1. @WebServlet("/logout")
  2. public class LogoutServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. HttpSession session = req.getSession(true);
  6. if(session.getAttribute("loggedUser") == null){
  7. resp.sendRedirect(req.getContextPath());
  8. return;
  9. }
  10. session.invalidate();
  11. resp.sendRedirect(getServletContext().getContextPath());
  12. }
  13. }

然后还有一些其他servlet,它们访问loggeduserid(如果我已登录)或迭代以下集合(如果我是guest)。问题是会话随时都可能失效:好奇的用户可以在执行另一个任务时注销,servlet可以对失效的会话调用“getattribute”(或“setattribute”),从而触发invalidstateexception。此外,当一些servlet向Map中添加某些内容时,可以访问Map,但是可以通过使用synchronizedmap来修复Map,因此这里真正的问题是会话可能随时失效。每次使用会话时使用“同步”是唯一的解决方案吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题