ViewExpiredException не выбрасывается на запрос ajax, если страница JSF защищена j_security_check, предоставляет решение, когда страница входа является страницей JSF. Но что, если страница входа в систему - это страница JSP?
У меня есть страница входа в jsp:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/core/login.jsp</form-login-page>
<form-error-page>/core/login.jsp</form-error-page>
</form-login-config>
</login-config>
На моей странице JSF (facelet), если я нажимаю кнопку не-Ajax, я буду перенаправлен на login.jsp. Если я нажму кнопку Ajax, он останется на той же странице JSF. Однако в обоих случаях код отладки, который я добавил на страницу входа в JSP, будет отображаться на консоли.
===
Я переписал страницу входа в систему, используя facelet вместо jsp
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/facelets/login.jsf</form-login-page>
<form-error-page>/facelets/login.jsf</form-error-page>
</form-login-config>
</login-config>
Я добавил AjaxLoginListener:
public class AjaxLoginListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
// return PhaseId.ANY_PHASE;
return PhaseId.RESTORE_VIEW;
}
@Override
public void beforePhase(PhaseEvent event) {
System.out.println(" **** AjaxLoginListener: Before Phase: " + event.getPhaseId());
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
System.out.println(" **** AjaxLoginListener: After Phase: " + event.getPhaseId());
FacesContext context = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
String loginURL = request.getContextPath() + "/facelets/login.jsf";
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: originalURL: " + originalURL + " Login URL: "+loginURL);
System.out.println(" **** AjaxLoginListener: After Phase: request.getRequestURI() " +request.getRequestURI());
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: isAjaxRequest " +context.getPartialViewContext().isAjaxRequest());
if (context.getPartialViewContext().isAjaxRequest()
&& originalURL != null
&& loginURL.equals(request.getRequestURI()))
{
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: AjaxRequest " + event.getPhaseId());
try {
context.getExternalContext().redirect(originalURL);
} catch (IOException e) {
e.printStackTrace();
throw new FacesException(e);
}
}
}
}
Как только я использовал facelet вместо jsp, я смог вызвать слушателя. Тем не менее, он никогда не переходит на страницу входа, потому что originalURL (RequestDispatcher.FORWARD_REQUEST_URI) всегда имеет значение NULL для запросов Ajax. Что я делаю неправильно?
Простым решением является добавление проверки, если пользователь вошел в систему, а если нет, для перенаправления на страницу входа:
@Override
public void afterPhase(PhaseEvent event) {
System.out.println(" **** AjaxLoginListener: After Phase: " + event.getPhaseId());
FacesContext context = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
HttpSession session = request.getSession();
// String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
String loginURL = request.getContextPath() + "/facelets/login.dti";
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: Login URL: "+loginURL);
System.out.println(" **** AjaxLoginListener: After Phase: request.getRequestURI() " +request.getRequestURI());
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: isAjaxRequest " +context.getPartialViewContext().isAjaxRequest());
if (context.getPartialViewContext().isAjaxRequest()
&& session.getAttribute("user") == null
&& loginURL.equals(request.getRequestURI()))
{
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: AjaxRequest " + event.getPhaseId());
try {
context.getExternalContext().redirect(loginURL);
} catch (IOException e) {
e.printStackTrace();
throw new FacesException(e);
}
}
}
Однако существенный недостаток здесь заключается в том, что после входа в систему он не пойдет на исходную страницу.
loginURL
соответственно? Что происходит, когда вы пытаетесь это сделать? Я не уверен, что понимаю вашу конкретную проблему. Обратите внимание, что я предполагаю, что вы абсолютно уверены, что у вас точно такая же проблема, как у ОП.