HttpSession超时后重定向

pho*_*360 10 java jsf timeout java-ee

我一直在看这个主题的很多帖子,但无法得到一个适用于我的案例的解决方案.

我正在使用带有JSF 2.0的Java EE 6(部署在JBoss AS 7.1上)

在我的web.xml身上:

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
Run Code Online (Sandbox Code Playgroud)

当会话自动超时时,我希望将用户重定向到登录页面.

我试过的:

方法1:使用过滤器

我试过以下过滤器:

@WebFilter()
public class TimeOutFilter implements Filter {

        @Override
        public void init(FilterConfig filterConfig) throws ServletException { 
        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {
        System.out.println("filter called");
        final HttpServletRequest req = (HttpServletRequest) request;
        final HttpSession session = req.getSession(false);
        if (session != null && !session.isNew()) {
            chain.doFilter(request, response);
        } else {
            System.out.println("Has timed out");
            req.getRequestDispatcher("/logon.xthml").forward(request, response);
        }
    }

    @Override
    public void destroy() {
    }
}
Run Code Online (Sandbox Code Playgroud)

web.xml我试过

<filter-mapping>
    <filter-name>TimeOutFilter</filter-name>
    <url-pattern>*.xhtml</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)

<filter-mapping>
    <filter-name>TimeOutFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)

过滤器在每次请求时都会调用(在控制台中记录"fiter called").但是,当会话超时时不会调用它.

方法2:HttpSessionLister

我试过用一个HttpSessionListerner.该方法称为具有以下签名:

public void sessionDestroyed(HttpSessionEvent se) {
}
Run Code Online (Sandbox Code Playgroud)

我无法重定向到特定页面.当我想重定向用户时,我通常使用NavigationHandlerfrom,FacesContext但在这种情况下没有FacesContext(FacesContext.getCurrentInstance()返回null).

根据这篇文章,HttpListener无法重定向用户,因为它不是请求的一部分.

解决这个问题的最佳方法是什么?我可以做些什么来使上述两种方法之一起作用?

Bal*_*usC 16

只要客户端未发送HTTP请求,您就无法发送HTTP响应.就那么简单.这就是HTTP的工作原理.如果任何网站能够在没有客户请求的情况下轻松推送HTTP响应,则互联网看起来会非常不同.

基于类似的回答客户端的键盘/鼠标活动JavaScript是基于心跳在这里,或间refresh头部等作为回答在这里,如果你已经基本上是一个单页web应用(因此,你不能有效使用会话范围将是解决办法但视图范围),但如果您在同一会话中的多个选项卡/窗口中打开页面,那将无法正常工作.

理论上,Websockets是向客户端推送内容的正确解决方案,但这又需要一个活动会话.鸡蛋问题.此外,它在当前仍然相对广泛使用的旧浏览器中不起作用,因此它目前仅应用于渐进增强.

最好的办法是定义一个错误页面,该页面处理最终用户在会话过期时调用操作的情况.另请参见javax.faces.application.ViewExpiredException:无法恢复视图.