如果有人写了一个 URL 并试图跳转登录页面,我该如何检查并将他重定向到登录页面?
您似乎使用的是本地身份验证。在这种情况下,您需要实现servlet filter。 JSF 将会话范围的托管 bean 存储为 HttpSession 的属性,因此您可以在 doFilter() 方法中检查它:
HttpServletRequest req = (HttpServletRequest) request;
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager");
if (userManager != null && userManager.isLoggedIn()) {
chain.doFilter(request, response);
} else {
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/login.xhtml");
}
将此过滤器映射到覆盖受保护页面的 URL 模式,例如/app/*.
当我返回并尝试与表单交互时,它会发送一条消息提醒我会话到期。发生这种情况时如何再次重定向到登录表单?
我知道这涉及 Ajax 请求?对于普通请求,您可以在web.xml 中使用<error-page>。如果在web.xml中给客户端设置状态保存方式如下
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
不是一个选项,那么你需要实现一个自定义的ExceptionHandler:
public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public void handle() throws FacesException {
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException();
if (exception instanceof ViewExpiredException) {
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired");
facesContext.renderResponse();
iter.remove();
}
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
(请注意,此特定示例导航到 viewexpired,因此它需要 /viewexpired.xhtml 作为错误页面)
以上需要通过以下ExceptionHandlerFactory实现烘焙:
public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new ViewExpiredExceptionHandler(parent.getExceptionHandler());
}
}
这又需要在faces-config.xml注册如下:
<factory>
<exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>