对于session过期跳转的问题,很简单,就是一个过滤器,然后判断session为空?跳转:继续。但是对于ajax的请求,需要做特殊处理,见下面代码中的
// 此处考虑ajax操作session过期的操作,如果ajax请求过程中session过期,则指定过期状态码为:911.
String requestType = req.getHeader("X-Requested-With");
因为ajax请求的时候请求头是:X-Requested-With,so我们可以根据该请求头做session过期处理。
下面是过滤器的实现,可以作为参考。
package com.***.action.util;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 标题:SessionFilter.
*
* 描述:session expire filter.
*
* @author lgscofield.
*/
public class SessionFilter implements Filter {
private final static Log LOGGER = LogFactory.getLog(SessionFilter.class);
/**
* 过滤器配置
*/
private FilterConfig filterConfig;
/**
* 超时页面
*/
protected String sessionTimeOutPage = null;
/**
* 某些url前缀列表(如: /css/*, /js/*, /images/***...)
*/
private List<String> ignoreURIs = new ArrayList<String>();
/**
* 静态资源列表(如: *.css, *.js, *.jpg...)
*/
private List<String> ignoreExts = new ArrayList<String>();
/**
* 个别动态资源(如: login.action, navigate.action, login.jsp...)
*/
private List<String> ignoreActions = new ArrayList<String>();
/**
* Default Construct.
*/
public SessionFilter() {
super();
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Init LogFilter Start.");
this.filterConfig = filterConfig;
// this.context = this.filterConfig.getServletContext();
// startMonitor();
// 某些URL前缀不予处理(例如 /img/***)
String ignores = filterConfig.getInitParameter("ignore");
if (ignores != null) {
for (String ig : StringUtils.split(ignores, ',')) {
ignoreURIs.add(ig.trim());
}
}
// 某些URL扩展名不予处理(例如 *.jpg)
ignores = filterConfig.getInitParameter("ignoreExts");
if (ignores != null) {
for (String ig : StringUtils.split(ignores, ',')) {
ignoreExts.add('.' + ig.trim());
}
}
// 某写页面及Action不予处理(例如login.jsp,login.action)
ignores = filterConfig.getInitParameter("ignoreActions");
if (ignores != null) {
for (String ig : StringUtils.split(ignores, ',')) {
ignoreActions.add(ig.trim());
}
}
LOGGER.info("Init LogFilter End.");
}
@Override
public void destroy() {
this.filterConfig = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
resp.setCharacterEncoding("UTF-8");
HttpSession session = req.getSession(true);
String requestUrl = req.getRequestURI();
String redirectPath = req.getContextPath() + "/navigate.action";
try {
//过滤URL前缀
/*
* for (String ignoreURI : ignoreURIs) { if (requestUrl.startsWith(ignoreURI)) { chain.doFilter(req, resp);
* return; } }
*/
//过滤URL后缀
for (String ignoreExt : ignoreExts) {
if (requestUrl.endsWith(ignoreExt)) {
chain.doFilter(req, resp);
return;
}
}
// 过滤登陆action/jsp
for (String ingonAction : ignoreActions) {
if (isContains(requestUrl, ingonAction)) {
chain.doFilter(req, resp);
return;
}
}
if (requestUrl.endsWith("/portal/") || requestUrl.endsWith("/portal")) {
resp.sendRedirect(redirectPath);
return;
}
} catch (SecurityException e) {
String loginPage = req.getContextPath() + URLEncoder.encode(requestUrl, "utf-8");
resp.sendRedirect(loginPage);
}
// 验证session是否过期
Object user = session.getAttribute("userInfo");
if (user == null) {
// 此处考虑ajax操作session过期的操作,如果ajax请求过程中session过期,则指定过期状态码为:911.
String requestType = req.getHeader("X-Requested-With");
if (!StringUtils.isEmpty(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")) {
resp.setStatus(911);
resp.setHeader("sessionstatus", "timeout");
resp.addHeader("loginPath", redirectPath);
return;
} else {
// wrapper.sendRedirect(redirectPath);
resp.sendRedirect(redirectPath);
return;
}
} else {
chain.doFilter(request, response);
return;
}
}
public static boolean isContains(String container, String regx) {
boolean result = false;
if (container.indexOf(regx) != -1) {
return true;
}
return result;
}
}
最后就是页面上的处理了,此处应用了jquery全局事件处理机制:
$(function(){ $.ajaxSetup({ contentType: "application/x-www-form-urlencoded;charset=utf-8", cache: false, complete: function(XHR, TS){ var resText = XHR.responseText; var sessionstatus = XHR.getResponseHeader("sessionstatus"); var loginPath = XHR.getResponseHeader("loginPath"); if (911 == XHR.status && "timeout" == sessionstatus) { // 此处使用了开源的消息确认框 $.messager.confirm('session过期', '您的会话已经过期,请重新登陆后继续操作!', function(confirm){ if (confirm) { window.location.replace(loginPath); } }); // 也可以使用下面的原生js的确认框,如果确认则跳转 if(window.confirm('session过期', '您的会话已经过期,请重新登陆后继续操作!')) { window.location.replace(loginPath); } return; } } }); });