检查会话是否存在JSF [英] Check if session exists JSF
问题描述
我有一个登录页面,在该页面上有一个User Bean,用于验证某人的用户名和密码.此Bean是会话范围的. 如果有人写了URL并试图跳出登录页面,我该如何检查并将其重定向到登录页面?
I have a login page where I have a User bean to authenticate username and password for a person. This Bean is Session Scoped. If someone writes a URL and tries to jump the login page, how can I check that and redirect him to the login page?
另一方面.假设我已经登录并且正在工作,突然间我出去了一段时间,会话期满了.当我返回并尝试与表单进行交互时,它会发送一条消息,提醒我会话到期.发生这种情况时,如何重新重定向到登录表单?
On the other hand. Suppose I have logged in and I was working and suddenly I go out for a while and my session expires. When I return and try to interact with the form it sends a message alerting me the session expiration. How can I redirecto again to the login form when this occurs?
先谢谢了.希望我能解释一下自己.
Thanks in advance. Hope I explain myself.
Mojarra 2.1.4,Tomcat 7,Tomahawk 1.1.11
Mojarra 2.1.4, Tomcat 7, Tomahawk 1.1.11
推荐答案
如果有人写了一个URL并试图跳出登录页面,我该如何检查并将其重定向到登录页面?
您似乎正在使用本地认证.在这种情况下,您需要实现 servlet过滤器. JSF将会话范围的托管bean作为HttpSession
的属性存储,因此您可以在doFilter()
方法中进行检查:
You seem to using homegrown authentication. In that case, you need to implement a servlet filter. JSF stores session scoped managed beans as attributes of HttpSession
, so you could just check on that in doFilter()
method:
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");
}
将此过滤器映射到覆盖受保护页面的网址格式,例如/app/*
.
Map this filter on an URL pattern covering the secured pages, e.g. /app/*
.
当我返回并尝试与表单进行交互时,它会发送一条消息,提醒我会话已过期.发生这种情况时,如何再次重定向到登录表单?
我了解这与Ajax请求有关?对于正常的请求,您可能在web.xml
中使用了<error-page>
.如果按照以下方式在web.xml
中将状态保存方法设置为客户端
I understand that this concerns Ajax requests? For normal requests you could have used an <error-page>
in web.xml
. If setting the state saving method to client in web.xml
as follows
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
is not an option, then you need to implement a custom 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
作为错误页面)
(note that this particular example navigates to viewexpired
, so it expects a /viewexpired.xhtml
as error page)
需要通过以下 ExceptionHandlerFactory
实现:
The above needs to be baked by the following ExceptionHandlerFactory
implementation:
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
中进行如下注册:
which in turn needs to be registered in faces-config.xml
as follows:
<factory>
<exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>
这篇关于检查会话是否存在JSF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!