日期:2014-05-16  浏览次数:20356 次

JSF Session timeout处理

在用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>