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

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

我有一个会话侦听器:

@WebListener
public class SessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        Set<Integer> follows = ConcurrentHashMap.newKeySet();
        se.getSession().setAttribute("userFollows", follows);
    }
}

我有一个loginservlet:

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* ... check parameters ... */

        try (Connection con = ConPool.getConnection()) {
            UserDAO service = new UserDAO(con);
            User user = service.get(username, true);
            if (user != null && user.getPassword().check(password) ) {
                HttpSession session = req.getSession(true);
                session.setAttribute("loggedUserId", user.getId());

                /* Adds guest's follows in db */
                Set<Integer> follows = (Set<Integer>) session.getAttribute("userFollows");
                if(!follows.isEmpty()) {
                    FollowDAO followService = new FollowDAO(con);
                    followService.insert(follows, user.getId());
                }

                resp.sendRedirect(req.getContextPath());
            } else {
                resp.sendError(400);
                return;
            }
        } catch (SQLException throwables) {
            throw new ServletException(throwables);
        }
    }

这是logoutservlet:

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(true);
        if(session.getAttribute("loggedUser") == null){
            resp.sendRedirect(req.getContextPath());
            return;
        }
        session.invalidate();
        resp.sendRedirect(getServletContext().getContextPath());
    }
}

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

暂无答案!

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

相关问题