`
yuzhi2217
  • 浏览: 36586 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JSF中session过期后视图恢复的问题

    博客分类:
  • JSF2
阅读更多

在jsf中,一旦session过期,生命周期为session的Controller bean对象将会被销毁,因此除了一些静态页面,大多数情况的动态页面视图也就无法恢复。如果没有在web.xml设置error page,那么系统会直接在页面中抛出异常。当然关掉页面重新打开就不会有这个问题,但是普通浏览者这个时候往往会不知所措,以为网站挂掉了,这样可用性会很差。

    一般网上提供的解决方法是在web.xml中设置error page来捕获错误,重定向到一个指定的页面,例如:
<error-page>     
<exception-type>javax.faces.application.ViewExpiredException</exception-type>     
<location>/login.jsf</location> 
</error-page>


    但悲惨的是,在调试中发现javax.faces.application.ViewExpiredException这个异常并不会被捕获到,com.sun.faces.lifecycle.LifecycleImpl的execute方法抛出的实际上是FacesException。我怀疑可能是jsf的2.0版本修改了这一块,而网上的解决方法是针对老版本的。

    如此,我们只能通过从com.sun.faces.lifecycle.LifecycleImpl派生一个类来处理这个异常,代码如下:

import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ppedu.commons.SystemProperty;
import com.sun.faces.lifecycle.LifecycleImpl;

public class TeleLifecycleImpl extends LifecycleImpl {

    public TeleLifecycleImpl() {
        super();
    }
     
    public void execute(FacesContext context) {
        try {
            super.execute(context);
        } 
        catch (ViewExpiredException  vee) {
            //似乎永远不会捕获,应该是异常在父类的同名方法中被包装成了FacesException
            redirect(context);
        }
        catch (FacesException fe) {
            //取得该异常的root cause
            Object obj= fe.getCause();
            //判断是否ViewExpiredException
            if (obj instanceof  ViewExpiredException){                
                redirect(context);
            }
            else{
                throw fe;
            }
        }
    }
     
    private void redirect(FacesContext context) {
        try {
            context.responseComplete();
            context.renderResponse();
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
            
            //根据原来的请求路径确定要重定向的路径
            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            String path = request.getRequestURI();
            String [] ss = path.split("/");            
            String redirectKey = "session.timeout.redirect.url.general";
            for(int i=0;i<ss.length;i++){
                if( ss[i].equals("security") || ss[i].equals("organManagementCenter") || ss[i].equals("webManageCenter")){
                    //管理模块
                    redirectKey = "session.timeout.redirect.url.management";
                    break;
                }
                if( ss[i].equals("usercenter")){
                    //个人中心
                    redirectKey = "session.timeout.redirect.url.usercenter";
                    break;
                }
            }
            //目标页面
            String url = context.getExternalContext().getRequestContextPath() + SystemProperty.getKeyValue(redirectKey);    
            response.sendRedirect(url);
        } catch (Exception e) {
            System.out.println("url redirect wrong ");
        }
    }
}


    这个类可以捕获ViewExpiredException引起的异常,将页面重定向到实现设定的url。com.ppedu.commons.SystemProperty是一个读配置文件的类,读者可以自己实现一个,配置文件设置了三个url,分别指向网站首页、用户中心登陆页和管理中心登录页,设置如下:

#============================================================================
# session过期后的默认页  
#============================================================================
session.timeout.redirect.url.general = /home.jsf
session.timeout.redirect.url.management = /security/managementLogin.jsf
session.timeout.redirect.url.usercenter = /usercenter/login.jsf


    然后,我们创建一个工厂类:

import com.sun.faces.lifecycle.LifecycleFactoryImpl;

public class TeleLifecycleFactoryImpl extends LifecycleFactoryImpl {
    public final static String CUSTOM_LIFECYCLE = "TELEEPOCH";    
    /** Creates a new instance of TeleLifecycleFactoryImpl */
    public TeleLifecycleFactoryImpl() {
        addLifecycle(CUSTOM_LIFECYCLE,new TeleLifecycleImpl());
    }
}

    接着,在faces-config.xml中注册这个工厂类来监查生命周期:

<factory>
        <lifecycle-factory>com.ppedu.view.TeleLifecycleFactoryImpl</lifecycle-factory>
</factory>


    OK,搞定收工,测试一下看看是否能获得预期效果。

分享到:
评论

相关推荐

    JSF中文教程jsf

    **生命周期** 是JSF处理请求的关键过程,包括初始化、恢复视图、应用请求值、处理事件、更新模型值、渲染响应等阶段。开发者可以在这些阶段插入自定义的行为。 **JSF与Java EE集成** 是其强大的特点之一。它可以...

    精通JSF中文教程精通JSF中文教程

    JSF组件有六个主要的生命周期阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和渲染响应。理解这些阶段对于优化性能和解决潜在问题至关重要。 **8. JSF与MVC模式** JSF遵循MVC设计模式,其中视图由...

    JSF Multiple Session都一個典型解決

    【JSF Multiple Session一个典型解决方案】 JavaServer Faces (JSF) 是Java平台上的一个用于构建Web应用程序的MVC(Model-View-Controller)框架。在处理用户会话时,JSF可能会遇到多重会话的问题,这可能导致数据...

    JSF如何监测和处理session超时

    本篇文章将详细介绍如何在JSF中监测和处理session超时,特别是通过监听恢复视图阶段的`ViewExpiredException`异常。 首先,我们需要理解JSF的生命周期。JSF有多个阶段,包括恢复视图(Restore View)阶段。在这个...

    JSF中文教程.zip

    6. **生命周期**:JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用、渲染响应和结束请求。每个阶段都有特定的任务,理解这个生命周期对于调试和优化JSF应用至关重要。 7. **转换和验证**...

    JSF中文教程+JSF参数传递方式

    5. **视图和会话范围的Bean**:JSF中的Managed Bean可以在不同的作用域中存在,如请求、会话、应用和视图。视图和会话范围的Bean特别适用于存储那些需要跨多个请求或页面保持的参数。 6. **导航案例**:JSF的导航...

    JSF中文问题解决方法完整版

    同时,确保在JSF的视图文件(通常是.xhtml)中,页面头部的`&lt;f:view&gt;`标签也指定了正确的编码。 ```xhtml ``` 4. **数据库配置**:数据库的编码设置也至关重要。确保数据库表和字段的字符集为UTF-8,以便正确存储...

    jsf中文使用教程jsf中文使用教程

    5. **国际化支持**:JSF支持多语言,这在“JSF中文使用教程”中可能包含如何设置和使用中文资源的内容。 **学习JSF的关键概念**: 1. **Facelet**:Facelets是JSF的默认视图技术,用于创建和组织用户界面组件。 2. ...

    jsf 中文帮助文档

    **生命周期** 是JSF处理请求的关键步骤,包括恢复视图、应用请求值、处理验证、更新模型值、调用后处理方法和渲染响应等多个阶段。理解每个阶段的作用可以帮助开发者有效地控制和调试应用程序。 此外,**...

    JSF帮助文档

    JSF生命周期包括六个主要阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和呈现响应。在这个过程中,JSF框架负责管理组件状态,处理用户事件,并与后端业务逻辑进行交互。 JSF提供了一种声明式编程...

    JSF的工作方式 JSF架构 JSF模型 JSF事件类型

    1. **恢复视图(Restore View)**:当客户端发起请求时,JSF首先检查是否存在先前创建的视图。如果存在,JSF会恢复这个视图,即重新构建组件树,确保服务器端的组件状态与上次用户交互时一致。 2. **应用请求值...

    jsf第一个例子 jsf架包 jsf实例

    1. **JSF生命周期**:JSF有六个主要阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用业务逻辑以及渲染响应。开发者可以在这些阶段插入自定义行为。 2. **JSF页面(Facelets)**:JSF使用Facelets...

    JSF入门(中文pdf)

    当一个JSF页面被请求时,它会经历一系列的阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑、以及渲染响应。开发者可以根据这些阶段插入自定义的行为,例如在验证阶段进行用户输入检查。 再者,JSF...

    JSF包,jsf包,JSF包,jsf包

    **生命周期**:JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑、渲染响应和结束请求。这个生命周期确保了数据的有效性,提供了错误处理,并管理了组件状态。 **JSF的优点**: 1. **...

    JSF教程(有关jsf实例的操作步骤)

    JSF组件经历了六步生命周期:恢复视图、应用请求值、处理验证、更新模型值、调用应用程序和呈现响应。每一步都提供了插入自定义行为的机会,如验证用户输入或执行业务逻辑。 **4. Facelets** Facelets是JSF的标准...

    JSF与hibernate整合的登陆

    JSF的生命周期包括六阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和渲染响应。 这个“JSF与Hibernate整合的登陆”项目为初学者提供了一个实践基础Web应用开发的良好起点,涵盖了前端UI设计、后端...

    jsf实现登录功能

    在这个"jsf实现登录功能"的例子中,我们将探讨如何利用JSF来构建一个基本的用户登录系统。 首先,登录功能通常包括两部分:前端页面和后端逻辑。在JSF中,前端页面通常由XHTML文件(.xhtml)组成,这些文件结合了...

    JSF实战(中文+英文)

    JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用程序、呈现响应和清理。每个阶段都有其特定的任务,例如在处理验证阶段,JSF会检查用户输入的有效性。 **JSF与Ajax** JSF提供了内置的...

    用jsf做的登录注册的组件

    9. **JSF生命周期**:理解JSF的请求处理流程对于调试和优化非常重要,包括恢复视图、应用请求值、验证、更新模型值和渲染响应等阶段。 10. **依赖注入**:JSF支持CDI(Contexts and Dependency Injection),可以...

Global site tag (gtag.js) - Google Analytics