zoukankan      html  css  js  c++  java
  • 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");
    这样。假设client是网页。它就会自己主动跳到登录页面。假设不是网页(如AJAX请求)。我们须要在client中推断返回的字符串中是否包括“SESSION_TIMEOUT_ERROR,假设有的话就做出跳到首页的处理。


    那么,如今轮到client了,由于使用的是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("系统提示", "注销异常,请联系管理人员!!");
    								}
    							});

    
    




  • 相关阅读:
    TOMCAT原理详解及请求过程
    详解Tomcat配置及使用
    Android网络编程(三)Volley使用方法全解析
    Android开发文档翻译之-Services
    竞赛中经常使用的C++写法
    Android消息机制
    boost的内存管理
    二叉树遍历技巧
    【 D3.js 视频系列 】 飞速入门
    [Spring实战系列](19)Servlet不同版本号之间的差别
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6762628.html
Copyright © 2011-2022 走看看