ViewExpiredException not throw on ajax request if JSF page is protected by 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) 对于 Ajax 请求始终为 NULL。做错了什么?