Как перенаправлять на страницу входа, когда сессия истек в веб-приложения Java?
Это неправильный вопрос. Вы должны различать случаи «Пользователь не вошел в систему» и «Сессия истекла». В основном вы хотите перенаправить на страницу входа, когда пользователь не вошел в систему. Не когда сеанс истек. Текущий принятый ответ проверяет только HttpSession#isNew()
. Но это, очевидно, не удается, когда пользователь отправил более одного запроса в тот же сеанс, когда сеанс неявно создан JSP или нет. Например. когда просто нажимаете F5 на странице входа.
Как уже говорилось, вместо этого вы должны проверить, вошел ли пользователь в систему или нет. Учитывая тот факт, что вы задаете такой вопрос, в то время как стандартные рамки проверки подлинности, такие как j_security_check
, Shiro, Spring Security и т. Д., Уже прозрачно управляют этим (и, следовательно, не нужно будет задавать этот вопрос на них), что может означает, что вы используете подход, основанный на подлинной аутентификации.
Предполагая, что вы храните в вошедшего пользователя в сеансе в некоторых логин 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);
}
}
}
Затем вы можете проверить, что в логине filter, как показано ниже:
@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()
чеков.
Почему бы не использовать SessionListener и перенаправлять на сессии уничтожены? –
@Mr_and_Mrs_D: потому что во время сеанса уничтожения не обязательно доступен HTTP-запрос. – BalusC