在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中文教程
jsf 中文文档jsf 中文文档jsf 中文文档jsf 中文文档
精通JSF中文教程精通JSF中文教程精通JSF中文教程精通JSF中文教程精通JSF中文教程精通JSF中文教程
JSF中文文档
NULL 博文链接:https://shmilywzc.iteye.com/blog/1322415
自己在网上查询整理出来的,欢迎交流! 从 JSF1.2 规范说明中,我们可以发现在恢复视图的生命周期时会抛出ViewExpiredException 异常,因此我们可在恢复视图的生命周期前做一些处理。
jsf的中文教程chm版的和讲解jsf中使用到的一些参数的传递方式,学习jsf很不错的材料……
jsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSFjsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSF
jsf 分页 jsf 分页 jsf 分页 jsf 分页
JSF 使用 Bean 来达到逻辑层与表现层分离的目的,Bean 的管理集中在组态档案中,您只要修改组态档案,就可以修改 Bean 之间的相依关系。 o Backing Beans o Beans 的组态与设定 o Beans 上的 List, Map 数据转换与...
jsf中文使用教程jsf中文使用教程
在未来的发展中,有可能所有的J2EE应用服务器都需要支持JSF。 Java Server Faces技术好处 引入了基于组件和事件驱动的开发模式,使开发人员可以使用类似于处理传统界面的方式来开发Web应用程序。提供了行为与...
Dhtml手册、 JSF中文教程、JSF API、struts2.0中文帮助手册.chm等等
JSF入门(中文pdf)
这里是jsf的tags的书籍。主要讲述jsf的用法。
博文链接:https://chicochen.iteye.com/blog/131729
《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF...
JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍
ajax4jsf中文用户指南,很全面。适合初学者
主要讲述JSF的工作方式 JSF的工作方式 JSF架构 JSF模型 JSF事件类型