Как переместить пользователя на страницу тайм-аута после окончания сеанса, если пользователь нажимает кнопку возврата браузера
Я обрабатываю истечение сессии в JSF 2.0, используя фильтр. Вот код
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HttpSession session = httpServletRequest.getSession(false);
if (session == null) {
//session timeout check.
if (httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid()) {
System.out.println("Session has expired");
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0"); // public user
httpServletResponse.sendRedirect(timeoutPage);
} else {
session = httpServletRequest.getSession(true);
session.setAttribute("logedin", "0");
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
} //end of doFilter()
Но проблема в том, что, когда сессия заканчивается, и если пользователь нажимает кнопку "Назад", он получает страницу со всей стилизацией. Есть ли в любом случае, что когда сеанс истекает, и если пользователь нажимает кнопку назад браузера, то он направляет на timeoutPage.
Еще одна вещь, что я также использую компонент Prime Faces на своей странице, например, датируемые. Я использую нумерацию страниц. Если время сеанса истекло, и я нажимаю на нумерацию страниц, сообщение об окончании сеанса не отображается. Кажется, что запрос ajax не вызывает фильтр? Как я могу связать свои события ajax, или вы можете сказать датируемые события нумерации страниц с истечением срока действия сессии?
Спасибо
1 ответ
когда сеанс истекает, и если пользователь нажимает кнопку "Назад", он получает страницу со всей стилизацией
Вы должны указать браузеру не кэшировать страницы в кэше браузера. Браузер должен вместо этого отправлять полный запрос на сервер.
Добавьте следующие строки прямо перед filterChain.doFilter()
вызов.
if (!httpServletRequest.getRequestURI().startsWith(httpServletRequest.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
httpServletResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
httpServletResponse.setDateHeader("Expires", 0); // Proxies.
}
Если время сеанса истекло, и я нажимаю на нумерацию страниц, сообщение об окончании сеанса не отображается. Кажется, что запрос ajax не вызывает фильтр?
AJAX-запросы JSF ожидают XML-ответов с HTTP-статусом 200. Если вы отправляете синхронное перенаправление, то будет отправляться HTTP-ответ 302, который будет полностью игнорироваться движком JSF AJAX. Вместо этого вы должны отправлять нормальный ответ HTTP 200 с определенным фрагментом XML, который сообщает движку JSF ajax выполнить перенаправление. Сделай это вместо httpServletResponse.sendRedirect()
затем:
if ("partial/ajax".equals(httpServletRequest.getHeader("Faces-Request"))) {
httpServletResponse.setContentType("text/xml");
httpServletResponse.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", timeoutPage);
}
else {
httpServletResponse.sendRedirect(timeoutPage);
}
Обратите внимание, что когда вы уже находитесь в контексте JSF (например, PhaseListener
или же SystemEventListener
или может быть @ManagedBean
), то вы могли бы просто использовать ExternalContext#redirect()
метод. Это будет прозрачно обрабатывать синхронные / асинхронные запросы соответственно.