session失效强制重新登录
实现原理:
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间。
实现步骤:
1. 创建一个拦截类SystemSessionInterceptor,实现HandlerInterceptor
package com.dacheng.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.dacheng.util.ConstantParameter;
public class SystemSessionInterceptor implements HandlerInterceptor {
//登录失效的提示,此处是用一个映射实现的,对应的jsp文件时sessionrun.jsp
public static final String Prompt_LOGIN_URL="/sessionrun";
Logger log = Logger.getLogger(getClass());
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession(true);
// session中获取用户名信息
Object obj = session.getAttribute(ConstantParameter.session_userId);
log.info("userId = " + obj);
log.info("RequestURI = "+request.getRequestURI());
if (obj == null || "".equals(obj.toString())) {
//如果判断是 AJAX 请求,直接设置为session超时
if( request.getHeader("x-requested-with") != null
&& request.getHeader("x-requested-with").equals("XMLHttpRequest") ) {
response.setHeader("sessionstatus", "timeout");
response.sendError(518, "session timeout.");
} else{
response.sendRedirect(
request.getSession().getServletContext().getContextPath()
+ ConstantParameter.Prompt_LOGIN_URL);
}
return false;
}
return true;
}
}
sessionrun.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="js/jquery.min.js" type="text/javascript">script>
<title>登录提示title>
head>
<body>
<script language="JavaScript">
alert("登录已失效,请重新登录。");
setTimeout(function () {
window.top.location.href="./loginTZBSM";
},2000);
script>
body>
html>
2.在SpringMVC中加入如下配置
需要注意的是:此处的拦截地址,因为我的jsp文件是在web-info下的,所以没能实现双映射地址的写法,例如 @RequestMapping(“/a/b”) ,也没能实现在controller类上加@RequestMapping 映射的方法,所以就在url映射上拼接了“interceptor”前缀,当做标识。(此处可忽略,如果遇到跟我相同问题的人可以借鉴)
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/interceptor*" />
<mvc:exclude-mapping path="/loginTZBSM" />
<bean class="com.dacheng.interceptor.SystemSessionInterceptor">bean>
mvc:interceptor>
mvc:interceptors>
3.对于返回一个页面的请求,如果检测到session失效可以直接以重定向的方式实现,如下:
response.sendRedirect( request.getSession().getServletContext().getContextPath()
+ ConstantParameter.Prompt_LOGIN_URL);
但是对于ajax请求,此方法是不能实现重新登录的,要用一下方法:
(1)在后台java文件中判断是否是ajax请求
//如果判断是 AJAX 请求,直接设置为session超时
if( request.getHeader("x-requested-with") != null
&& request.getHeader("x-requested-with").equals("XMLHttpRequest") ) {
response.setHeader("sessionstatus", "timeout");
response.sendError(518, "session timeout.");
}
(2)对应的需要使用该功能的jsp中加入以下代码
/**
* 设置未来(全局)的AJAX请求默认选项
* 主要设置了AJAX请求遇到Session过期的情况
*/
$.ajaxSetup({
type: 'POST',
complete: function(xhr,status) {
var sessionStatus = xhr.getResponseHeader('sessionstatus');
if(sessionStatus == 'timeout') {
//强制重新登录
alert("由于您长时间没有操作, session已过期, 请重新登录.");
window.location.href = './loginTZBSM';
}
}
});
至此设置完成