日期:2014-05-16 浏览次数:20364 次
在用JSF做项目的时候,经常会碰到session timeout问题,比如部署在tomcat下的时候,默认的timeout时间为30分钟,则在30分钟以后,点击页面上的任何commandButton或commandLink都会导致抛出javax.faces.application.ViewExpiredException异常:
?
提供一种解决方式:
?
自定义PhaseListener,并且在RESTORE_VIEW阶段的beforePhase中进行处理
<lifecycle> <phase-listener>com.tcb.flow.webui.jsf.listener.AuthenticationPhaseListener</phase-listener> </lifecycle>
?AuthenticationPhaseListener的代码如下:
?
package com.test.listener; import javax.faces.FacesException; import javax.faces.application.Application; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.test.Constants; public class AuthenticationPhaseListener implements PhaseListener { private static final Log logger = LogFactory.getLog(AuthenticationPhaseListener.class); public void afterPhase(PhaseEvent event) { // other operation } public void beforePhase(PhaseEvent event) { FacesContext context = event.getFacesContext(); ExternalContext externalContext = context.getExternalContext(); HttpSession session = (HttpSession) externalContext.getSession(false); boolean newSession = session == null || session.isNew(); boolean postBack = !externalContext.getRequestParameterMap().isEmpty();//form submit if (newSession && postBack) {//timeout ViewHandler viewHandler = context.getApplication().getViewHandler(); UIViewRoot viewRoot = viewHandler.createView(context, "/index.jsp"); context.setViewRoot(viewRoot); context.renderResponse(); try { viewHandler.renderView(context, viewRoot); context.responseComplete(); } catch (Exception e) { throw new FacesException("Session is timeout", e); } } } public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } }
?如果是new session且是表单提交则跳转到登录页面。
?
【附faces-config.xml配置信息】
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> <lifecycle> <phase-listener>com.tcb.flow.webui.jsf.listener.AuthenticationPhaseListener</phase-listener> </lifecycle> <application> <action-listener>com.tcb.flow.webui.jsf.listener.AuthenticationActionListener</action-listener> <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver> <message-bundle>resource.messages</message-bundle> <resource-bundle> <description>i18n message for framework</description> <base-name>resource.messages</base-name> <var>msg</var> </resource-bundle> <resource-bundle> <description>i18n message for common action</description> <base-name>com.action.package</base-name> <var>comMsg</var> </resource-bundle> <resource-bundle> <description>i18n message for action used by managing user</description> <base-name>com.action.manage.package</base-name> <var>mgrMsg</var> </resource-bundle> <resource-bundle>