检查会话是否存在JSF
我有一个login页面,我有一个用户bean来authentication一个人的用户名和密码。 这个Bean是会话作用域。 如果有人写了一个URL并尝试跳转login页面,我该如何检查并将其redirect到login页面?
另一方面。 假设我已经login,我正在工作,突然间我出去了一会儿,我的会议到期。 当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话到期。 发生这种情况时,如何重新导向到login表单?
提前致谢。 希望我解释一下自己。
Mojarra 2.1.4,Tomcat 7,Tomahawk 1.1.11
如果有人写了一个URL并尝试跳转login页面,我该如何检查并将其redirect到login页面?
你似乎使用本土authentication。 在这种情况下,你需要实现一个servletfilter 。 JSF存储会话作用域托pipebean作为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"); }
将此filter映射到覆盖受保护页面的URL模式,例如/app/*
。
当我返回并尝试与表单进行交互时,会发送一条消息,提醒我会话到期。 发生这种情况时,如何重新导向login表单?
我明白,这涉及Ajax请求? 对于一般的请求,你可以在web.xml
使用<error-page>
。 如果在web.xml
中将状态保存方法设置为client,如下所示
<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>
如果你正在实现自己的系统,你可以添加一个属性给用户称为会议或任何。 该属性可以是布尔值,因此无论何时开始,您都可以将此属性设置为true。 编写一个名为permission的方法例如:
public void permission() throws IOException { if(userStatelessBean.getSession() == false) { System.out.println("*** The user has no permission to visit this page. *** "); ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); context.redirect("login.xhtml"); } else { System.out.println("*** The session is still active. User is logged in. *** "); } }
在你想要限制的每个jsf页面上( 对于这个例子 ),你可以在页面的最开始处添加下面的代码:
<f:metadata> <f:event type="preRenderView" listener="#{sesija.permission()}"/> </f:metadata>
这个要做的是在呈现页面之前调用带有对象名称sesija的JSF ManagedBean,并检查您在指定方法中创build的rulles是否满足。
我希望你觉得这个有用,
谢谢。