基于ExtJs的JavaScript拦截器

原文地址:http://blog.csdn.net/jaune161/article/details/18135607 转载请注明出处

Java后台有拦截器的功能,但是Js前台是没有这个概念的,最近做项目需要对前台返回的信息做统一的处理,于是就想到了能不能在前台也做一个类似与拦截器的功能,对后台返回的消息做统一的处理,然后用了半天的时间完成了这个功能,现在奉上代码。


Java消息类,统一向处理向前台返回的消息

package com.zrhis.base.model;

import java.util.List;
import java.util.Map;

import org.directwebremoting.annotations.DataTransferObject;


@SuppressWarnings("rawtypes")
@DataTransferObject
public class Message {
	private Boolean isError;//是否是错误信息
	private String errorCode;//错误代码
	private Boolean success;//请求是否成功
	private Boolean isException;//是否抛出异常,抛出异常则success为false,优先级大于success
	private String exName;//异常名称
	private String exDetails;//异常详细信息
	private String message;
	/****前台分页相关*****/
	private Integer totalPage;//总页数
	private Integer totalCount;//总记录数
	private Integer currentPage;//当前页数
	private Integer pageSize;//分页大小
	private List roots;//记录
	private Object data;
	private Boolean flag;//操作是否成功
	private Boolean isSessionOut;	//session是否失效标志
	private Map<String,Object> metaData;

 .......getter and setter........
}

在项目中使用@ExceptionHandler对异常做了统一的处理,如果抛出异常则isException=true。

	/**
	 * 公共异常处理,URL请求返回异常页面,Ajax请求返回json数据
	 * @param request HttpServletRequest
	 * @param response HttpServletResponse
	 * @param ex Exception
	 * @return
	 */
	@ExceptionHandler(Exception.class)
	public ModelAndView exception(HttpServletRequest request,
		HttpServletResponse response,Exception ex){
		if(logger.isWarnEnabled()){
			logger.warn("异常信息", ex);
		}
		//判断是否是Ajax请求
		boolean isAjaxRequest = this.isAjaxRequest(request);
		//获取异常的详细信息
		Message msg = MessageManager.exception(ex);
		
		if(isAjaxRequest){
			//Ajax请求处理
			PrintWriter out = ControllerTools.getWriter(response);
			JSONObject data = JSONFormat.toJson(msg,false);
			out.print(data.toString());
			return null;
		}else{
			//URL请求处理
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("message", msg.getMessage());
			map.put("isError", true);
			map.put("exceptionName", msg.getExName());
			return new ModelAndView("error/exception",map);
		}
	}

采用拦截器的方式来处理Session的问题,如果Session失效则isSessionOut=true,拦截器部分省略,跟上面的异常处理差不多。

下面是Js部分:

拦截器类

/**
 * 抽象类
 * 任何要实现拦截器都需要继承自这个类,并实现其中的interceptor方法,并添加至拦截器池中,就可以实现拦截功能
 */
Ext.define('Xzr.web.AbstractInterceptor',{
	
	alternateClassName:['Xzr.AbstractInterceptor'],
	
	statics:{
		BEFORE:'before', //在请求前拦截
		ATTER:'after',   //在请求过后拦截
		AROUND:'around'  //在请求前后都拦截
	},
	
	mode:'after',
	
	isInterceptor:true,
	
	//不包含的URL
	excludes:[],
	
	//仅包含URL,优先级大于excludes
	includes:[],
	
	/**
	 * 拦截方法,执行拦截及验证过程
	 * @param {Object} options The options config object passed to the request method.
	 * @param {Object} response The XHR object containing the response data. See The XMLHttpRequest Object for details.
	 * @return {Boolean}
	 */
	interceptor:Ext.emptyFn(),
	
	constructor:function(interceptorFn){
		var me = this;
		
		if(Ext.isObject(interceptorFn)){
			//me.interceptor = interceptorFn;
			Ext.apply(me,interceptorFn);
		}else if(Ext.isFunction(interceptorFn)){
			me.interceptor = interceptorFn;
		}
	},
	
	getId:function(){
		return this.id;
	},
	/**
	 * 处理拦截过程
	 * @param {} options
	 */
	handler:function(options,response){
		return this.interceptor(options,response);
	},
	/**
	 * 验证URL是否需要拦截
	 * @param {String} url 需要验证的地址
	 */
	validationUrl:function(url){
		var me = this,
			intercept = false;
		
		//如果配置了include就仅验证包含的URL
		//如果配置了excludes就仅不包含excludes中的URL
		//如果都没有配置就拦截所有URL
		if(me.includes.length == 0 && me.excludes.length == 0){
			intercept = true;
		}else if(me.includes.length>0){
			//满足条件说明需要拦截
			Ext.Array.each(this.includes,function(reg){
				//url.match(reg)
				var reg = new RegExp(reg);
				if(reg.test(url))intercept = true;
				return false;
			});
		}else{
			intercept = true;
			Ext.Array.each(this.excludes,function(reg){
				var reg = new RegExp(reg);
				if(reg.test(url))intercept = false;
				return false;
			});
		}
		
		return intercept;
	}
});


重新定义Ext.Ajax类

Ext.define('Ext.Ajax',{
	extend: 'Ext.data.Connection',
	
	singleton: true,
    
	autoAbort: false,
	//是否允许在请求前拦截
	enableBeforeInterceptor:false,
    
	interceptors:Ext.create('Ext.util.MixedCollection'),
	
	//执行拦截操作
	invokeInterceptor:function(options,response,mode){
		var me = this;
		
		this.interceptors.each(function(interceptor){
			//判断拦截器类型
			if(interceptor.mode == mode || 
				interceptor.mode == Xzr.AbstractInterceptor.AROUND ){
				//执行拦截操作,如果没有通过拦截器则返回false
				if(interceptor.handler(options,response) === false){
					return false;
				};
			}
		});
		
		return true;

	},
	//通过listener实现对Ajax访问的拦截
	listeners :{
		//拦截器处理,如果没有通过拦截器,则取消请求
		beforerequest:function( conn, options, eOpts ){
			if(this.enableBeforeInterceptor){
				return this.invokeInterceptor(options,null,'before');
			}
			return true;
		},
		//请求完成后对数据验证,无法中断后续的操作,具体请研究ExtJs源码。
		requestcomplete:function(conn, response, options, eOpts){
			return this.invokeInterceptor(options,response,'after');
		}
	},
	
	/**
	 * 添加拦截器
	 * @param {String} interceptorId
	 * @param {Xzr.web.AbstractInterceptor} interceptor
	 */
	addInterceptor:function(interceptor){
		if(!interceptor)return;
		
		if(Ext.isString(interceptor)){
			interceptor = Ext.create(interceptor);
		}
		
		this.interceptors.add(interceptor.getId(),interceptor);
	}
});

实现对后台异常的拦截

Xzr.web.ExceptionInterceptor

/**
 * 异常拦截器,处理后台返回的有异常信息的请求
 */
Ext.define('Xzr.web.ExceptionInterceptor',{
	extend:'Xzr.web.AbstractInterceptor',
	
	interceptor:function(options,response){
		
		var resultData = Ext.decode(response.responseText);
		
		if(resultData.isException){
			Ext.MessageBox.alert(resultData.exName,resultData.message);
			return false;
		}
		if(resultData.isSessionOut){
			Ext.MessageBox.alert('Session超时','Session超时,请重新登录!',function(){
				window.location = Ext.CONTEXT+'login';
			});
			return false;
		}
		
		return true;
	}
	
});

最后一步,将拦截器添加到拦截器池中

Ext.Ajax.addInterceptor('Xzr.web.ExceptionInterceptor');

最后展示一下效果,哈哈

后台返回异常信息

exName: "Exception"
isError: true
isException: true
message: "org.hibernate.exception.SQLGrammarException: could not extract ResultSet"
success: false



Session超时

isSessionOut: true
success: false

基于ExtJs的JavaScript拦截器_第1张图片

通过这种方法可以实现对后台返回的数据做统一的处理,而不需要在使用Ajax时再一遍一遍的重复解析。同时对store,model等请求有作用。因为他们都是基于Ajax的吗!


-------------------------------------------------------------End--------------------------------------------------------


你可能感兴趣的:(JavaScript,ExtJs,Js拦截器)