ExtJS4.2.1与Spring MVC实现Session超时控制

如果你的项目使用ExtJS作为表现层,你会发现,SESSION超时控制将是一个问题。

本文将就自己的经验,来解决这一问题,当然,解决问题并非只有一种方法,我只是提出我的方法。

首先,做超时控制,必需使用过滤器,而我们既然使用了Spring MVC,那就用拦截器取代吧,写一个拦截器,用来拦截用户请求,当然,这个拦截器还需要可以配置哪些请求是不需要拦截的。

/**
 *
 */
package net.bioslink.business.intercepter;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.bioslink.common.util.ConfigureUtil;
import net.bioslink.common.vo.Constants;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * @author leoly
 *
 */
@Repository
public class SystemAccessInterceper extends HandlerInterceptorAdapter {
	private final Logger logger = Logger.getLogger(getClass());

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		String uri = request.getRequestURI();
		String[] noFilters = ConfigureUtil.getStringArray("no_filter_setting");
		boolean isFilter = true;
		if (!ArrayUtils.isEmpty(noFilters)) {
			for (String u : noFilters) {
				if (uri.contains(u)) {
					isFilter = false;
					break;
				}
			}
		}

		if (isFilter) {
			// Session
			Object obj = request.getSession()
					.getAttribute(Constants.SESSION_ID);
			if (null == obj) {
				logger.info("登录超时!!");
				PrintWriter writer = response.getWriter();
				writer.print("<script>top.location='http://127.0.0.1:8080/VkDesktop/login/loginSystem.do';</script>SESSION_TIMEOUT_ERROR");
				IOUtils.closeQuietly(writer);
				return false;
			} else {
				request.setAttribute("LOG_ACCESS_TIME",
						System.currentTimeMillis());
				logger.info(obj + "访问了" + uri);
			}
		}
		return super.preHandle(request, response, handler);
	}

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		super.afterCompletion(request, response, handler, ex);
		Object obj = request.getAttribute("LOG_ACCESS_TIME");
		if (null != obj) {
			long accessTime = (long) obj;
			logger.info("处理请求" + request.getRequestURI() + "耗时"
					+ (System.currentTimeMillis() - accessTime) + "毫秒!");
		}
	}
}

然后,将这个拦截器注册到Spring MVC中,在xxx-servlet.xml文件中添加注册代码:

	<mvc:interceptors>
		<bean class="net.bioslink.business.intercepter.SystemAccessInterceper" />
	</mvc:interceptors>

OK,现在这个拦截器已经开始工作了,它会拦截用户请求,判断SESSION中是否存在登录信息,如果不存在,则说明已经超时,拦截器向客户问写一段代码

writer.print("<script>top.location='http://127.0.0.1:8080/VkDesktop/login/loginSystem.do';</script>SESSION_TIMEOUT_ERROR");

这样,如果客户端是网页,它就会自动跳到登录页面,如果不是网页(如AJAX请求),我们需要在客户端中判断返回的字符串中是否包含“SESSION_TIMEOUT_ERROR”,如果有的话就做出跳到首页的处理。

那么,现在轮到客户端了,因为使用的是ExtJS,几乎所有的请求都是AJAX请求,所以判断SESSION_TIMEOUT_ERROR是关键。那总不能所有的AJAX请求都加上这些判断吧??OMG,杀了我吧,可怜的码农……

其实,我们可以写一个TimeoutControl类,封装一些我们需要修改和添加的东西,来实现超时跳转功能!谁叫ExtJS提供了这么多类功能(继承,重写,覆盖)呢?

我们知道,ExtJS的请求虽然都是AJAX请求,但是却可以区分为Store请求和一般的AJAX请求,那么我们的TimeoutControl类就需要重新构造这些请求方式,并且,以后写的所有请求都需要使用这个类来完成。

Ext.define('Ext.ux.TimeoutControl', {
	extend : 'Ext.data.Store',
	alias : 'widget.timeoutstore',
	constructor : function(config) {
		Ext.apply(config.proxy, {
			listeners : {
				exception : function(self, response) {
					var responseText = response.responseText;
					if (responseText
							&& responseText.indexOf("SESSION_TIMEOUT_ERROR") > 0) {
						top.location = '../login/loginSystem.do';
					}
				}
			}
		});
		this.callParent([config]);
	},

	statics : {
		request : function(config) {
			var f = config.success;
			config.success = Ext.Function.createInterceptor(f, function(
							response) {
						var txt = response.responseText;
						// alert(txt);
						if (txt && txt.indexOf("SESSION_TIMEOUT_ERROR") > 0) {
							top.location = '../login/loginSystem.do';
							return false;
						}

						return true;
					});
			Ext.Ajax.request(config);
		}
	}
});

这个类中,我们继承了Ext.data.Store,并且在构造器中动态加入了一个proxy的exception处理函数,也就是说,只要使用此类,无论Store的proxy中写没写exception函数,都会在这里添加上,而这个函数就是处理超时控制的。然后,这个类还提供了一个静态方法request,这个request方法会调用Ext.Ajax.request(config),但是在调用之前,我们给配置的success函数添加了一段判断超时的代码,使用的是ExtJS的函数拦截方法,效果杠杠的。

最后,只要我们在使用到Store的地方中使用Ext.ux.TimeoutControl类,在使用Ext.Ajax.request的地方中使用Ext.ux.TimeoutControl.request取代,那么,超时控制就完成了。

使用Store的例子:

		var store = Ext.create('Ext.ux.<span style="font-size:18px; white-space: pre; background-color: rgb(240, 240, 240);">TimeoutControl</span>', {
					model : 'MyDesktop.data.WorkOrderModule',
					remoteSort : true,
					remoteFilter : true,
					sorters : [new Ext.util.Sorter({
								property : 'reportId',
								direction : 'ASC'
							})],
					proxy : {
						type : 'ajax',
						actionMethods : {
							read : 'POST'
						},
						extraParams : {
							projectCode : "44190008",
							orderMonth : 2,
							id : 0
						},
						pageParam : 'pageNo',
						limitParam : 'pageSize',
						url : '../lebang/workOrder/queryWorkorderList.do',
						reader : {
							type : 'json',
							root : 'orders',
							totalProperty : 'totalCount'
						}
					}
				});

使用AJAX请求的例子:

					Ext.ux.TimeoutControl.request({
								url : "../user/logout.do",
								timeout : 60000,
								method : 'POST',
								disableCaching : false,
								params : {},
								success : function(response) {
									window.location = '../login/loginSystem.do';
								},
								failure : function() {
									Ext.Msg.alert("系统提示", "注销异常,请联系管理人员!!");
								}
							});

ExtJS4.2.1与Spring MVC实现Session超时控制

时间: 2024-10-13 21:58:04

ExtJS4.2.1与Spring MVC实现Session超时控制的相关文章

Spring MVC中Session的正确用法&lt;转&gt;

Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的设计模式遍及各处,使得其框架虽然学习曲线陡峭,但 一旦掌握则欲罢不能.初学者并不需要过多了解框架的实现原理,随便搜一下如何使用“基于注解的controller”就能很快上手,而一些书籍诸如 “spring in action”也给上手提供了非常优良的选择. 网上的帖子多如牛毛,中文的快速上手,英文的

spring mvc 使用session

spring mvc 使用session spring mvc 使用session

【译】理解Spring MVC Model Attribute 和 Session Attribute

作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用时,理解这些作用域,如何将数据与对象和这些作用域交互是十分重要的.[在 StackOverflow 上有一篇文章可以帮助你快速了解 request 和 session 作用域] SPRING MVC 作用域 当我开始用 Spring MVC 编写 Web 应用时,我发现 Spring model 和

理解Spring MVC Model Attribute和Session Attribute

作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用时,理解这些作用域,如何将数据与对象和这些作用域交互是十分重要的.[在 StackOverflow 上有一篇文章可以帮助你快速了解 request 和 session 作用域] SPRING MVC 作用域 当我开始用 Spring MVC 编写 Web 应用时,我发现 Spring model 和

Spring Mvc Session超时easyui tab页中ajax请求跳出问题

<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射,添加拦截器,类级别的处理器映射 --> 拦截器配置 public class HandlerInterceptor1 extends HandlerInterceptorAdapter {//此处一般继承HandlerInterceptorAdapter适配器即可 @Override public boolean preHandle(HttpServletRequest request, HttpServletResp

Spring MVC集成Spring Data Reids和Spring Session实现Session共享

说明:Spring MVC中集成Spring Data Redis和Spring Session时版本是一个坑点,比如最新版本的Spring Data Redis已经不包含Jedis了,需要自行引入.且最新版本的2.0.1会与Spring MVC 4.1.4有冲突,估计写法错了.所以要明确引入的Spring MVC版本和Spring Data Redis和Spring Session版本. 小提示:如果想要官方明确的版本可以参考Spring Boot的版本,比如我使用了1.4.7的Spring

Spring Session在Spring MVC中的使用.md

Web项目会通过Session进行会话保持,Session是保存在服务器内存中: 现在为了提高站点的性能和稳定性,将Web项目发布到多个服务器,通过代理如Nginx或F5做负载均衡: 由于负载均衡正常配置,会对客户端的请求随机转发到某一个服务器,这会导致Session丢失: 解决方案:一种是可将代理如Nginx或F5配置为高可用,即用户访问时,在同一会话期间内,只往一台服务器转发:另一种是引入Spring Session,对Session进行持久化.统一管理: Spring Session对Se

理解Spring MVC Model Attribute 和 Session Attribute

作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用时,理解这些作用域,如何将数据与对象和这些作用域交互是十分重要的.SPRING MVC 作用域当我开始用 Spring MVC 编写 Web 应用时,我发现 Spring model 和 session attribute 有一点神秘,尤其当它们与我熟知的 HTTP request 和 sessio

编写Spring MVC Controller

1.映射请求 在POJO类定义处标注@Controller,再通过<content:component-scan /...>扫描相应的类包,即可使POJO类成为一个能处理HTTP请求的控制器. 如何将请求映射到对应的控制器的方法中是Spring MVC框架最重要的任务之一,这项任务由@RequestMapping注释承担. 例子1: 1 @Controller 2 public class UserController{ 3 4 @RequestMapping(value="/use