如何在Java Web应用程序中会话过期时重定向到登录页面?
这是一个错误的问题。您应该区分“用户未登录”和“会话已过期”的情况。您基本上希望在用户未登录时重定向到登录页面。会话过期时不可以。当前接受的答案仅检查 。但是,当用户在同一会话中发送了多个请求时,当会话是由 JSP 隐式创建的,或者不是这样,这显然会失败。例如,只需在登录页面上按F5即可。HttpSession#isNew()
如前所述,您应该检查用户是否已登录。鉴于您正在问此类问题,而标准身份验证框架(如,Shiro,Spring Security等)已经透明地管理了这个问题(因此没有必要对它们提出此类问题),这只能意味着您正在使用自行开发的身份验证方法。j_security_check
假设您将会话中的登录用户存储在某个登录 servlet 中,如下所示:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@EJB
private UserService userService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/home");
} else {
request.setAttribute("error", "Unknown login, try again");
doGet(request, response);
}
}
}
然后,您可以在如下所示的登录过滤器中进行检查:
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
// ...
}
无需摆弄脆性支票。HttpSession#isNew()