JSF ページが j_security_check によって保護されている場合、ViewExpiredException が ajax 要求でスローされないは、ログイン ページが 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 ログイン ページに追加したデバッグ コードはコンソールに表示されます。
===
jsp の代わりに facelet を使用してログイン ページを書き直しました。
<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);
}
}
}
}
jsp の代わりに facelet を使用すると、リスナーを呼び出すことができました。ただし、Ajax リクエストの場合、元の URL (RequestDispatcher.FORWARD_REQUEST_URI) は常に NULL であるため、ログイン ページに移動することはありません。何が間違っていますか?