Javaweb项目session超时解决方案
在java web开发中,session为我们提供了很多方便,session是由浏览器和服务器之间维护的。session超时理解为:浏览器和服务器之间创建了一个session,由于客户端长时间(休眠时间)没有与服务器交互,服务器将此session销毁,客户端再一次与服务器交互时之前的session就不存在了。
0.需求
需要对所有的/web/**请求进行登录拦截,session超时时跳转到登录页面。
1.引入
一般来说,在项目使用中都会配置session超时时间,如果不配置,则默认值为30分钟,即用户不操作30分钟以后,session就会失效,此时用户就需要重新登录系统。
session超时时间的配置主要的项目的web.xml中进行配置,如下:
<span style="font-size: 14px;"> <!-- 设置session超时时间 -->
<session-config>
<!-- 分钟 -->
<session-timeout>60</session-timeout>
<!-- 去除url上显示的jsessionid, 防止打开tab页时出现js错误 -->
<tracking-mode>cookie</tracking-mode>
</session-config></span><span style="font-size:24px;">
</span>
2.请求的分类
现在的项目中请求主要分为两种:一种是普通请求,即发起请求返回视图和模型;另外一种是ajax请求,主要返回模型数据。后端进行处理时就要根据不同的请求返回不同的内容。
对于普通请求,我们直接返回javascript脚本,脚本内容可以是将页面跳转到登录页面。
对于ajax请求,则需要返回非200的状态码,这样ajax请求才会进入到error回调函数中以及全局的ajax错误回调函数ajaxerror中。
3.后端处理session超时
后端采用springmvc的拦截器处理,这里为什么用拦截器呢?一方面,请求url不能限制的太死,比如/*,这样对所有的请求都进行过滤是浪费资源的。另一方面,有些url不需要进行拦截处理,比如到登录页面的请求肯定是不能拦截,要不然会循环重定向。再一方面,我们只需要拦截控制器请求,其它请求不拦截。
下面看一下拦截器的实现:
/**
* web端登录拦截器
* 处理请求时session失效的问题,包含ajax请求和普通请求
* @classname weblogininterceptor
* @author zhangshun
* @date 2016年10月20日 上午11:14:52
*/
public class weblogininterceptor extends handlerinterceptoradapter{
/**
* 日志对象
*/
private logger logger = loggerfactory.getlogger(weblogininterceptor.class);
/**
* 默认注销url
* 即session超时后,发起请求到此地址,只对普通请求有效
*/
private static final string default_logout_url = "/web/logout";
/**
* 注销url
*/
private string logouturl;
@override
public boolean prehandle(httpservletrequest request, httpservletresponse response,
object handler) throws exception {
user user = sessionutils.getuserfromrequestacrosscas(request);
string uri = request.getrequesturi();
if(user == null){
response.setcontenttype("text/html;charset=utf-8");
if(request.getheader("x-requested-with") != null
&& request.getheader("x-requested-with").equalsignorecase("xmlhttprequest")){
// ajax请求, 前段根据此header进行处理
response.setheader("sessiontimeout", "session time out, you need relogin !");
// 返回未认证的状态码(401)
response.setstatus(httpstatus.unauthorized.value());
logger.debug("请求路径:" + uri + ", 请求方式 :ajax请求, session超时, 需要重新登录!");
}else{
// 普通请求
string path = request.getcontextpath();
stringbuffer basepath = new stringbuffer()
.append(request.getscheme())
.append("://")
.append(request.getservername())
.append(":")
.append(request.getserverport())
.append(path)
.append("/");
stringbuffer responsestr = new stringbuffer()
.append("<html><header><script type=\"text/javascript\">")
.append("window.location.href=\"")
.append(basepath).append(getlogouturl()).append("\";")
.append("</script></header></html>");
response.getwriter().write(responsestr.tostring());
logger.debug("请求路径:" + uri + ",请求方式 :普通请求, session超时, 需要重新登录!");
}
return false;
}
return true;
}
public string getlogouturl() {
// 使用默认值
if(stringutils.isempty(logouturl)){
return default_logout_url;
}
return logouturl;
}
public void setlogouturl(string logouturl) {
this
}
通过获取session中的user对象是否存在来判断session是否超时,如果session超时,则根据不同的请求方式进行返回。如果是普通请求,则直接返回javascript脚本,该脚本可以将页面跳转到其它url。如果是ajax请求,则返回401状态码,并且在返回的header中加入sessiontimeout,该数据将会在前端使用。
该拦截器在springmvc配置文件中的配置如下:
<span style="font-size:14px;"><!-- mvc拦截器 --> <mvc:interceptors> <!-- web登录拦截器 --> <mvc:interceptor> <mvc:mapping path="/web/**"/> <mvc:exclude-mapping path="/web/index"/><!-- 防止循环重定向到首页 --> <mvc:exclude-mapping path="/web/login"/> <mvc:exclude-mapping path="/web/logout"/> <mvc:exclude-mapping path="/web/dologin"/> <bean class="com.woyi.mhub.interceptor.weblogininterceptor"/> </mvc:interceptor> </mvc:interceptors></span><span style="font-size:24px;"> </span>
4.前端处理session超时
对于普通请求,后端返回的是javascript脚本,会立刻执行,这里前端不需要任何处理。
对于ajax请求,后端返回401状态码,并在header中设置的sessiontimeout。这里使用jquery的ajaxcomplete回调函数处理,具体如下:
// 实现ajax请求时判断session是否失效 $(document).ajaxcomplete(function(event, response, settings) { var sessiontimeout = response.getresponseheader("sessiontimeout"); if(sessiontimeout != null && typeof sessiontimeout != "undefined" && sessiontimeout.length > 0){ // 这里写session超时后的处理方法 } });
好了,可以了,session超时的用户都会得到处理。
总结
关于javaweb项目session超时解决方案就到这里,希望对大家有所帮助。
上一篇: 对MySQL几种联合查询的通俗解释
下一篇: 去掉mysql连接时报警声音的方法