处理“会话过期” 在 JSF Web 应用程序中,在 JBoss AS 5 中运行

发布于 2024-07-24 14:44:37 字数 940 浏览 15 评论 0原文

这个问题与我的另一个问题“Java Web 应用程序中会话过期时如何重定向到登录页面?"。 以下是我想要做的事情:

  1. 我有一个在 JBoss AS 5 上运行的 JSF Web 应用程序
  2. 当用户处于非活动状态(例如 15 分钟)时,我需要注销用户并将其重定向到登录页面(如果他)正在尝试在会话过期后使用该应用程序。
  3. 因此,按照“JSF 注销和重定向”中的建议,我实现了一个过滤器它检查会话过期情况,如果会话已过期,则将用户重定向到 session-timed-out.jsp 页面。
  4. 我在 web.xml 中的所有其他过滤器定义之上添加了 SessionExpiryCheckFilter,这样我的会话过期检查将始终获得第一个命中。

现在是我面临的挑战。 由于我使用的是 JBoss AS,因此当会话过期时,JBoss 会自动将我重定向到登录页面(请注意,不会调用会话过期检查过滤器)。 因此,在我登录后,我的 SessionExpiryCheckFilter 会拦截该请求,并且它会看到会话可用。 但是,它抛出异常 javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces 无法恢复。

以前有人遇到过这个问题吗? 有什么想法可以解决这个问题吗?

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:

  1. I've a JSF web application running on JBoss AS 5
  2. 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.
  3. 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.
  4. 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.

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.

Have anyone faced this issue before? Any ideas to solve this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情域 2024-07-31 14:44:37

以下方法对我有用。 请注意,您必须使用 JSTL 核心 taglib 重定向而不是 jsp 重定向才能使其正常工作(因为 jsp 也会过期)。

在您的 FacesConfig.xml 中,输入以下内容:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/sessionExpired.jsf</location>
</error-page>

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" />

您还可以将此方法用于其他用途错误类型或异常。 例如,该元素包含错误代码或异常类型与 Web 应用程序中的资源路径之间的映射。:

<error-page>
    <error-code>400</error-code>
    <location>/400.html</location>
</error-page>

或元素包含 Java 异常类型的完全限定类名。

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/servlet/ErrorDisplay</location>
</error-page>

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).

In your FacesConfig.xml you put the following:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/sessionExpired.jsf</location>
</error-page>

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.:

<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.

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/servlet/ErrorDisplay</location>
</error-page>
魂牵梦绕锁你心扉 2024-07-31 14:44:37

如果您正在使用 Mojarra/Sun RI,您可能想尝试将其添加到您的 web.xml 中:

<context-param>
    <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name> 
    <param-value>true</param-value>
</context-param>

但是请注意,这并不总是完美的解决方案。 它隐藏了用户已丢失会话的事实。

If you are using Mojarra/Sun RI you might want to try to add this to your 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.

萧瑟寒风 2024-07-31 14:44:37

实现 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;
}

在 faces-config.xml 中恢复视图注册

Implement javax.faces.event.PhaseListener for Restore view

@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

吝吻 2024-07-31 14:44:37

我建议编写一个与过滤器结合使用的会话侦听器。

当会话过期时,您可以创建一个新的会话对象并为新对象设置超时值。

只需检查过滤器中的超时值并重定向浏览器即可。

请参阅 http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener .htm

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

琴流音 2024-07-31 14:44:37

我尝试为其编写一个过滤器,但有些它对我不起作用,所以我做了一个
替代它。

我在每个我不希望用户在没有登录的情况下访问的页面中都这样做了:

<f:view>
    <h:dataTable value="#{userHome.validuser()}"/>
     // my code
<f:view/>

这将调用我的会话托管 bean 中的函数 validuser()

现在这是我的职责。
在登录期间,我已经将用户对象插入到会话中。

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();
        }
} 

如果存在会话但没有人登录,那么它将带您进入重定向页面。

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文