原文地址: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........ }
/** * 公共异常处理,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); } }
下面是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
isSessionOut: true success: false
通过这种方法可以实现对后台返回的数据做统一的处理,而不需要在使用Ajax时再一遍一遍的重复解析。同时对store,model等请求有作用。因为他们都是基于Ajax的吗!
-------------------------------------------------------------End--------------------------------------------------------