Java 处理 JSF Web 应用程序中的“会话过期”,在 JBoss AS 5 中运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1030892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handling 'session expired' in JSF web application, running in JBoss AS 5
提问by Veera
This question is related to my other question "How to redirect to Login page when Session is expired in Java web application?". Below is what I'm trying to do:
这个问题与我的另一个问题“ Java Web 应用程序中的会话过期时如何重定向到登录页面?”有关。以下是我正在尝试做的事情:
- I've a JSF web application running on JBoss AS 5
- When the user is inactive for, say 15 minutes, I need to log out the user and redirect him to the login page, if he is trying to use the application after the session has expired.
- So, as suggested in 'JSF Logout and Redirect', I've implemented a filter which checks for the session expired condition and redirects the user to a session-timed-out.jsp page, if the session has expired.
- I've added SessionExpiryCheckFilter on top of all other filter definitions in web.xml, so that my session expiry check will get the first hit always.
- 我有一个在 JBoss AS 5 上运行的 JSF Web 应用程序
- 当用户处于非活动状态时,比如说 15 分钟,如果他在会话过期后尝试使用该应用程序,我需要注销用户并将他重定向到登录页面。
- 因此,正如“ JSF 注销和重定向”中所建议的,我实现了一个过滤器,用于检查会话过期条件并将用户重定向到 session-timed-out.jsp 页面(如果会话已过期)。
- 我在 web.xml 中的所有其他过滤器定义之上添加了 SessionExpiryCheckFilter,这样我的会话到期检查将始终获得第一个命中。
Now comes the challenge I'm facing. Since I'm using JBoss AS, when the session expired, JBoss automatically redirects me to the login page (note that the session expiry check filter is not invoked). So, after I log-in, my SessionExpiryCheckFilter intercepts the request, and it sees a session is available. But, it throws the exception javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.
现在是我面临的挑战。由于我使用的是 JBoss AS,当会话过期时,JBoss 会自动将我重定向到登录页面(注意没有调用会话过期检查过滤器)。因此,在我登录后,我的 SessionExpiryCheckFilter 拦截了请求,并且它看到一个会话可用。但是,它抛出异常javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.
Have anyone faced this issue before? Any ideas to solve this issue?
有没有人遇到过这个问题?有什么想法可以解决这个问题吗?
采纳答案by Chris Dale
The following approach works for me. Note that you have to use the JSTL core taglib redirect and not the jsp redirect in order for this to work (as the jsp also expires).
以下方法对我有用。请注意,您必须使用 JSTL 核心 taglib 重定向而不是 jsp 重定向才能使其工作(因为 jsp 也会过期)。
In your FacesConfig.xmlyou put the following:
在您的FacesConfig.xml 中,您输入以下内容:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/sessionExpired.jsf</location>
</error-page>
sessionExpired.jsp:
sessionExpired.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:redirect url="/login.jsf" />
You can also use this approach for other error types or exceptions. For example the element contains a mapping between an error code or exception type and the path of a resource in the web application.:
您也可以将此方法用于其他错误类型或异常。例如,该元素包含错误代码或异常类型与 Web 应用程序中资源路径之间的映射。:
<error-page>
<error-code>400</error-code>
<location>/400.html</location>
</error-page>
or element contains a fully qualified class name of a Java exception type.
或元素包含 Java 异常类型的全限定类名。
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/servlet/ErrorDisplay</location>
</error-page>
回答by Koekiebox
I would suggest writing a session listener in conjunction with the filter.
我建议结合过滤器编写一个会话侦听器。
When the session expires you can create a new session object and set a timeout value on the new object.
当会话到期时,您可以创建一个新的会话对象并在新对象上设置超时值。
Just check for the timeout value in the filter and redirect the browser.
只需检查过滤器中的超时值并重定向浏览器即可。
See http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener.htm
见http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener.htm
回答by skytteren
If you are using Mojarra/Sun RI you might want to try to add this to your web.xml:
如果您使用的是 Mojarra/Sun RI,您可能想尝试将其添加到您的 web.xml 中:
<context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param>
However be aware that this isn't always the perfect solution. It hides the fact that the user has lost its session.
但是请注意,这并不总是完美的解决方案。它隐藏了用户丢失会话的事实。
回答by keith
Implement javax.faces.event.PhaseListener for Restore view
为恢复视图实现 javax.faces.event.PhaseListener
@Override
public void afterPhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
if(facesContext.getViewRoot()==null){
try{
facesContext.getExternalContext().redirect(HOME_PAGE);
facesContext.responseComplete();
} catch (IOException e){
e.printStackTrace();
}
}
}
@Override
public void beforePhase(PhaseEvent event) {}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
register in faces-config.xml
在faces-config.xml 中注册
回答by ifti
I tried to write a filter for it but some how it was not working for me, so I made an alternate for it.
我试图为它编写一个过滤器,但它对我不起作用,所以我为它做了一个替代。
I did it like this in every page that I don't want the user to access without Login:
我在每个我不希望用户在没有登录的情况下访问的页面中都是这样做的:
<f:view>
<h:dataTable value="#{userHome.validuser()}"/>
// my code
<f:view/>
This will call the function validuser()
which is in my session managed bean.
这将调用validuser()
我的会话管理 bean 中的函数。
Now this is my function. During login I already insert the user object into the session.
现在这是我的功能。在登录期间,我已经将用户对象插入到会话中。
public void validuser()
{
FacesContext context = FacesContext.getCurrentInstance();
UserLogin ul = (UserLogin) context.getExternalContext().getSessionMap().get("userbean");
if (ul == null)
try{
context.getExternalContext().redirect("/HIBJSF/faces/LoginPage.xhtml");
context.responseComplete();
}
catch (IOException e)
{
e.printStackTrace();
}
}
If there is a session but no one had logged in, then it will take you to a redirect page.
如果有一个会话但没有人登录,那么它会带你到一个重定向页面。