在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与Java EE集成** 是其强大的特点之一。它可以...
JSF组件有六个主要的生命周期阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和渲染响应。理解这些阶段对于优化性能和解决潜在问题至关重要。 **8. JSF与MVC模式** JSF遵循MVC设计模式,其中视图由...
【JSF Multiple Session一个典型解决方案】 JavaServer Faces (JSF) 是Java平台上的一个用于构建Web应用程序的MVC(Model-View-Controller)框架。在处理用户会话时,JSF可能会遇到多重会话的问题,这可能导致数据...
本篇文章将详细介绍如何在JSF中监测和处理session超时,特别是通过监听恢复视图阶段的`ViewExpiredException`异常。 首先,我们需要理解JSF的生命周期。JSF有多个阶段,包括恢复视图(Restore View)阶段。在这个...
6. **生命周期**:JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用、渲染响应和结束请求。每个阶段都有特定的任务,理解这个生命周期对于调试和优化JSF应用至关重要。 7. **转换和验证**...
5. **视图和会话范围的Bean**:JSF中的Managed Bean可以在不同的作用域中存在,如请求、会话、应用和视图。视图和会话范围的Bean特别适用于存储那些需要跨多个请求或页面保持的参数。 6. **导航案例**:JSF的导航...
同时,确保在JSF的视图文件(通常是.xhtml)中,页面头部的`<f:view>`标签也指定了正确的编码。 ```xhtml ``` 4. **数据库配置**:数据库的编码设置也至关重要。确保数据库表和字段的字符集为UTF-8,以便正确存储...
5. **国际化支持**:JSF支持多语言,这在“JSF中文使用教程”中可能包含如何设置和使用中文资源的内容。 **学习JSF的关键概念**: 1. **Facelet**:Facelets是JSF的默认视图技术,用于创建和组织用户界面组件。 2. ...
**生命周期** 是JSF处理请求的关键步骤,包括恢复视图、应用请求值、处理验证、更新模型值、调用后处理方法和渲染响应等多个阶段。理解每个阶段的作用可以帮助开发者有效地控制和调试应用程序。 此外,**...
JSF生命周期包括六个主要阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和呈现响应。在这个过程中,JSF框架负责管理组件状态,处理用户事件,并与后端业务逻辑进行交互。 JSF提供了一种声明式编程...
1. **恢复视图(Restore View)**:当客户端发起请求时,JSF首先检查是否存在先前创建的视图。如果存在,JSF会恢复这个视图,即重新构建组件树,确保服务器端的组件状态与上次用户交互时一致。 2. **应用请求值...
1. **JSF生命周期**:JSF有六个主要阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用业务逻辑以及渲染响应。开发者可以在这些阶段插入自定义行为。 2. **JSF页面(Facelets)**:JSF使用Facelets...
当一个JSF页面被请求时,它会经历一系列的阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑、以及渲染响应。开发者可以根据这些阶段插入自定义的行为,例如在验证阶段进行用户输入检查。 再者,JSF...
**生命周期**:JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑、渲染响应和结束请求。这个生命周期确保了数据的有效性,提供了错误处理,并管理了组件状态。 **JSF的优点**: 1. **...
JSF组件经历了六步生命周期:恢复视图、应用请求值、处理验证、更新模型值、调用应用程序和呈现响应。每一步都提供了插入自定义行为的机会,如验证用户输入或执行业务逻辑。 **4. Facelets** Facelets是JSF的标准...
JSF的生命周期包括六阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用和渲染响应。 这个“JSF与Hibernate整合的登陆”项目为初学者提供了一个实践基础Web应用开发的良好起点,涵盖了前端UI设计、后端...
在这个"jsf实现登录功能"的例子中,我们将探讨如何利用JSF来构建一个基本的用户登录系统。 首先,登录功能通常包括两部分:前端页面和后端逻辑。在JSF中,前端页面通常由XHTML文件(.xhtml)组成,这些文件结合了...
JSF有七个阶段,包括恢复视图、应用请求值、处理验证、更新模型值、调用应用程序、呈现响应和清理。每个阶段都有其特定的任务,例如在处理验证阶段,JSF会检查用户输入的有效性。 **JSF与Ajax** JSF提供了内置的...
9. **JSF生命周期**:理解JSF的请求处理流程对于调试和优化非常重要,包括恢复视图、应用请求值、验证、更新模型值和渲染响应等阶段。 10. **依赖注入**:JSF支持CDI(Contexts and Dependency Injection),可以...