struts2之json请求的异常处理方案

来源:互联网 发布:unity3d制作吃豆人 编辑:程序博客网 时间:2024/06/06 05:25

大家都知道,使用struts2的异常处理机制,只要几行配置,就可以在发生异常时,跳转到我们指定的页面,并显示出相应的异常信息,具体的使用操作过程如下:

1)struts.xml

<struts><include file="struts-default.xml"></include>    <constant name="struts.devMode" value="true" /><!-- 实现国际化资源文件和struts配置文件自动重新加载,不需要重启服务器 -->    <constant name="struts.ui.theme" value="simple" />    <constant name="struts.action.extension" value="," /><!-- 不要后缀 -->    <constant name="struts.enable.SlashesInActionNames" value="true" /><!-- 使用"/"的方式 -->    <package name="hatch" namespace="" extends="json-default"><!-- json支持  -->...<!-- 定义全局视图 -->    <global-results><result name="login" type="redirectAction">login</result><result name="404">/WEB-INF/view/404.jsp</result><result name="500">/WEB-INF/view/500.jsp</result>    </global-results>    <!-- 定义全局异常-->    <global-exception-mappings><exception-mapping result="500" exception="java.lang.Exception"/><!-- 出现异常时,将页面转到500这个错误页面 -->    </global-exception-mappings>...</struts>

2)500.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>程序异常</title><%@include file="/WEB-INF/view/common/common.jspf" %><style type="text/css">*{margin:0;padding:0;}.errTitle{min-width:300px;width:90%;height:50px;line-height:50px;border:1px solid #999999;border-radius:5px;background:#0169B2;text-align:center;word-spacing:10px;font-family:'黑体';font-size:24px;margin:10px 70px;padding: 4px 4px 4px 6px;position:relative;}.showErrWrap{font-size:10px;position:absolute;right:10px;bottom:-5px;}.showErrWrap a:link,.showErrWrap a:visited{text-decoration:none;color:black;}.showErrWrap a:hover{text-decoration:underline;color:yellow;}.showErrWrap span{margin:0 4px;color:black;}.errStack{min-width:300px;width:90%;font-family:"Courier New", Courier, monospace;border:0 none;margin:10px 70px;overflow:auto;padding:4px;}</style><script type="text/javascript">$(function(){$('#showErrBtn').toggle(function(){$('#showErrBtn').text('关闭详情');$('.errStack').slideDown('normal');},function(){$('.errStack').slideUp('normal');$('#showErrBtn').text('查看详情');});});if (window.parent != window) {window.parent.location.href = window.location.href;}</script></head><body><div class="errTitle">程 序 出 现 异 常!<span class="showErrWrap"><a href="javascript:void(0);" id="showErrBtn">查看详情</a><span>|</span><a href="javascript:void(0);" onclick="javascript:history.go(-1);">返回上一页</a></span></div><div class="errStack" style="display:none;"><pre><s:property value="exceptionStack"/><!-- 异常信息 --></pre></div></body></html>

假设在UserAction.java中有一个跳转到列表页面的方法,如下:

/* 用户列表视图 */public String list() {int i = 10/0;return "list";}

这样,在出现异常时,就能到这个页面了,效果大约是下面的样子:


但现在我很多请求处理,使用的都是ajax提交请求并获取数据的方式,这种情况下,默认的异常处理就力不从心了。跑个题儿先,稍微介绍下struts2中ajax请求的配置方式,以下以用户列表为例:

1)添加jar包支持:struts2-json-plugin-2.3.4.jar

2)在自己的struts.xml中,package继承json-default

3)返回类型为json

4)Action中添加设置返回的数据的值

如下是配置:

<struts><constant name="struts.devMode" value="true" /><!-- 实现国际化资源文件和struts配置文件自动重新加载,不需要重启服务器 --><constant name="struts.ui.theme" value="simple" /><constant name="struts.action.extension" value="," /><!-- 不要后缀 --><constant name="struts.enable.SlashesInActionNames" value="true" /><!-- 使用"/"的方式 --><package name="hatch" namespace="" extends="json-default"> <!-- json支持 -->...<action name="user/*" class="userAction" method="{1}">            <result name="list">/WEB-INF/view/sys/user/list.jsp</result>            <result name="saveOrUpdate">/WEB-INF/view/sys/user/saveOrUpdate.jsp</result>            <result name="assginRole">/WEB-INF/view/sys/user/assginRole.jsp</result>            <result type="json">                <param name="root">dataMap</param>                <param name="excludeProperties">rows\[\d+\]\.department.parent,rows\[\d+\]\.department.users,rows\[\d+\]\.department.children,rows\[\d+\]\.roles</param>            </result><!-- ajax请求的返回视图 -->        </action>
如下是页面:

<html xmlns="http://www.w3.org/1999/xhtml"><head><%@include file="/WEB-INF/view/common/common.jspf"%><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>用户列表</title><script type="text/javascript">$(function(){//用户列表初始化$('#dg').datagrid({striped : true,rownumbers : true,singleSelect : false,pagination : true,pageSize : 10,fitColumn : true,dataType : 'json',animate : true,loadMsg : '请稍候...',        url:'${ctx }/sys/user/doList',         columns:[[  {field:'ck',checkbox:true,align:'center'},                  {title:'序号',field:'id',align:'center'},                  {title:'登录名',field:'username',align:'center'},                  {title:'名称',field:'name',align:'center'},                  {title:'性别',field:'gender',align:'center',formatter:function(v){ return v==1?'男':'女' }},                  {title:'手机',field:'phoneNumber',align:'center'},                  {title:'email',field:'email',align:'center'},                  {title:'所属部门',field:'department',align:'center',formatter:function(v){if(v)return v['name'];}},                  {title:'操作',field:'Operation',align:'center',formatter: operationFormate}                 ]],     });//easyui的列表请求,返回数据为json//添加操作列function operationFormate(value,node){  var str='<a style="color:green;text-decoration:none;margin-right:4px;" href="javascript:void(0);" onclick="update('+node.id+')">修改</a>'  +'<a style="color:red;text-decoration:none;margin-right:4px;" href="javascript:void(0);" onclick="del('+node.id+')">删除</a>'  +'<a style="color:green;text-decoration:none;margin-right:4px;" href="javascript:void(0);" onclick="assignrole('+node.id+')">角色分配</a>'  +'<a style="color:red;text-decoration:none;" href="javascript:void(0);" onclick="resetPwd('+node.id+')">密码重置</a>';          return str;      }//查询用户$('#queryBtn').click(function(){var queryParams = $('#dg').datagrid('options').queryParams;var name = $.trim($('#queryForm').find('input[name=name]').val());var gender = $.trim($('#queryForm').find('select[name=gender]').val());        queryParams.name = name;          queryParams.gender = gender;          $('#dg').datagrid('options').queryParams=queryParams;    $('#dg').datagrid('reload');});//添加用户$('#addBtn').click(function(){window.location.href="${ctx}/sys/user/save";});//删除用户$('#delBtn').click(function(){var ss = new Array();var rows = $('#dg').datagrid('getSelections');for(var i=0; i<rows.length; i++){var row = rows[i];ss.push(row.id);}del(ss.join(','));});});//修改用户function update(id){window.location.href="${ctx}/sys/user/update?id="+id;}//删除用户function del(ids){$.messager.confirm('确认框', '确认要删除吗?此操作是不可恢复的', function(r){if (r){ var url = '${ctx }/sys/user/del';$.post(url, {ids:ids}, function(data){if(data.result==0){$('#dg').datagrid('reload'); }else{$.messager.alert('error','失败');}alert(data.result);},'json');}});} //分配角色function assignrole(id){window.location.href="${ctx}/sys/user/assginRole?id="+id;} //密码重置function resetPwd(id){var url = '${ctx }/sys/user/doResetPwd1';$.post(url, {id:id}, function(data){if(data.result==0){$.messager.alert('信息提示','修改成功,密码重置为111111!','info');}else{var msg = data.msg; $.messager.alert('错误提示','操作失败!','error');window.location = "${ctx}/jsonHandlerAction";}},'json');}</script></head><body><div class="ptitle">系统管理>>用户列表</div><div class="content-wrap"><div class="pcontent"><div class="easyui-panel toolbar"><a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-add" plain="true" id="addBtn">新建</a><a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-remove" plain="true" id="delBtn">删除</a><s:form action="/user/doList" namespace="/"  method="post" id="queryForm">名称:<s:textfield name="name"/>性别:<s:select list="#{null:'全部',1:'男',2:'女'}" name="gender"/><a href="javascript:void(0);" class="easyui-linkbutton" iconCls="icon-search" id="queryBtn">Search</a></s:form></div><!-- 列表 --><table id="dg" title=""></table></div></div></body>
如下是Action

/* 用户 列表数据 */public String doList(){HttpServletRequest re = ServletActionContext.getRequest();dataMap = new HashMap<String, Object>();Map<String, Object> cond = MapBeanUtil.transBean2Map(user);Page<User> p = new Page<User>();cond.put("page", Integer.parseInt(re.getParameter("page")));cond.put("rows", Integer.parseInt(re.getParameter("rows")));p = userService.findUserForPage(cond);dataMap.put("total", p.getTotal());dataMap.put("rows", p.getRows());return SUCCESS;}
效果如下:



以上是json开发的简单介绍,更详细的可以下载相关文档。

返回正题,假如正在我在Action中出现异常,可怕的事情:框架将错误页面的html代码以html的形式返回来了,以下是用firefox看到的结果:


分析思考:

struts2的异常处理,是基于拦截器的,出现目前的错误,就是因为拦截器的异常处理,没有考虑到ajax异步请求,那么是哪个拦截器处理异常呢?打开struts核心包struts2-core-2.3.4.jar中的struts-default.xml中,查看下面的信息:

<interceptors>            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>            <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>。。。
发现异常是这个类com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor来处理的,因此,一个最简单的办法,就是将该类覆写,加上json请求的支持。

/* * Copyright 2002-2006,2009 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.opensymphony.xwork2.interceptor;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import org.apache.struts2.StrutsStatics;import com.hatch.common.JsonHandlerException;import com.opensymphony.xwork2.Action;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;import com.opensymphony.xwork2.util.ValueStack;import com.opensymphony.xwork2.util.logging.Logger;import com.opensymphony.xwork2.util.logging.LoggerFactory;/** * <!-- START SNIPPET: description --> *  * This interceptor forms the core functionality of the exception handling * feature. Exception handling allows you to map an exception to a result code, * just as if the action returned a result code instead of throwing an * unexpected exception. When an exception is encountered, it is wrapped with an * {@link ExceptionHolder} and pushed on the stack, providing easy access to the * exception from within your result. *  * <b>Note:</b> While you can configure exception mapping in your configuration * file at any point, the configuration will not have any effect if this * interceptor is not in the interceptor stack for your actions. It is * recommended that you make this interceptor the first interceptor on the * stack, ensuring that it has full access to catch any exception, even those * caused by other interceptors. *  * <!-- END SNIPPET: description --> *  * <p/> * <u>Interceptor parameters:</u> *  * <!-- START SNIPPET: parameters --> *  * <ul> *  * <li>logEnabled (optional) - Should exceptions also be logged? (boolean * true|false)</li> *  * <li>logLevel (optional) - what log level should we use ( * <code>trace, debug, info, warn, error, fatal</code>)? - defaut is * <code>debug</code></li> *  * <li>logCategory (optional) - If provided we would use this category (eg. * <code>com.mycompany.app</code>). Default is to use * <code>com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor</code>. * </li> *  * </ul> *  * The parameters above enables us to log all thrown exceptions with stacktace * in our own logfile, and present a friendly webpage (with no stacktrace) to * the end user. *  * <!-- END SNIPPET: parameters --> *  * <p/> * <u>Extending the interceptor:</u> *  * <p/> *  * <!-- START SNIPPET: extending --> *  * If you want to add custom handling for publishing the Exception, you may * override * {@link #publishException(com.opensymphony.xwork2.ActionInvocation, ExceptionHolder)} * . The default implementation pushes the given ExceptionHolder on value stack. * A custom implementation could add additional logging etc. *  * <!-- END SNIPPET: extending --> *  * <p/> * <u>Example code:</u> *  * <pre> * <!-- START SNIPPET: example --> * <xwork> *     <package name="default" extends="xwork-default"> *         <global-results> *             <result name="error" type="freemarker">error.ftl</result> *         </global-results> *  *         <global-exception-mappings> *             <exception-mapping exception="java.lang.Exception" result="error"/> *         </global-exception-mappings> *  *         <action name="test"> *             <interceptor-ref name="exception"/> *             <interceptor-ref name="basicStack"/> *             <exception-mapping exception="com.acme.CustomException" result="custom_error"/> *             <result name="custom_error">custom_error.ftl</result> *             <result name="success" type="freemarker">test.ftl</result> *         </action> *     </package> * </xwork> * <!-- END SNIPPET: example --> * </pre> *  * <p/> * This second example will also log the exceptions using our own category * <code>com.mycompany.app.unhandled<code> at WARN level.  *  * <pre> * <!-- START SNIPPET: example2 --> * <xwork> *   <package name="something" extends="xwork-default"> *      <interceptors> *          <interceptor-stack name="exceptionmappingStack"> *              <interceptor-ref name="exception"> *                  <param name="logEnabled">true</param> *                  <param name="logCategory">com.mycompany.app.unhandled</param> *                  <param name="logLevel">WARN</param>         *              </interceptor-ref> *              <interceptor-ref name="i18n"/> *              <interceptor-ref name="staticParams"/> *              <interceptor-ref name="params"/> *              <interceptor-ref name="validation"> *                  <param name="excludeMethods">input,back,cancel,browse</param> *              </interceptor-ref> *          </interceptor-stack> *      </interceptors> *  *      <default-interceptor-ref name="exceptionmappingStack"/> *     *      <global-results> *           <result name="unhandledException">/unhandled-exception.jsp</result> *      </global-results> *  *      <global-exception-mappings> *           <exception-mapping exception="java.lang.Exception" result="unhandledException"/> *      </global-exception-mappings> *         *      <action name="exceptionDemo" class="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingAction"> *          <exception-mapping exception="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingException" *                             result="damm"/> *          <result name="input">index.jsp</result> *          <result name="success">success.jsp</result>             *          <result name="damm">damm.jsp</result> *      </action> *  *   </package> * </xwork> * <!-- END SNIPPET: example2 --> * </pre> *  * @author Matthew E. Porter (matthew dot porter at metissian dot com) * @author Claus Ibsen */public class ExceptionMappingInterceptor1 extends AbstractInterceptor {protected static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingInterceptor.class);protected Logger categoryLogger;protected boolean logEnabled = false;protected String logCategory;protected String logLevel;public boolean isLogEnabled() {return logEnabled;}public void setLogEnabled(boolean logEnabled) {this.logEnabled = logEnabled;}public String getLogCategory() {return logCategory;}public void setLogCategory(String logCatgory) {this.logCategory = logCatgory;}public String getLogLevel() {return logLevel;}public void setLogLevel(String logLevel) {this.logLevel = logLevel;}@Overridepublic String intercept(ActionInvocation invocation) throws Exception {String result;try {result = invocation.invoke();} catch (Exception e) {ActionContext actionContext = invocation.getInvocationContext();HttpServletRequest request = (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);if (isAjaxRequest(request)) {//如果是ajax请求方式ValueStack stack = invocation.getStack();List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();JsonHandlerException je = new JsonHandlerException(e);String mappedResult = this.findResultFromExceptions(exceptionMappings, je);result = mappedResult;Map<String, Object> dataMap = new HashMap<String, Object>();stack.set("dataMap", dataMap);dataMap.put("result", "500");StringBuffer msg = new StringBuffer(e.toString()+"\n");            StackTraceElement[] trace = e.getStackTrace();            for (int i=0; i < trace.length; i++)            msg.append("\tat " + trace[i]+"\n");ServletActionContext.getRequest().getSession().setAttribute("errMsg", msg);}else{// 默认处理方式if (isLogEnabled()) {handleLogging(e);}List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();String mappedResult = this.findResultFromExceptions(exceptionMappings, e);if (mappedResult != null) {result = mappedResult;publishException(invocation, new ExceptionHolder(e));} else {throw e;}invocation.getStack();invocation.getInvocationContext().get(Action.ERROR);//invocation.getStack().findString("exceptionStack");invocation.getInvocationContext().get(Action.ERROR);}}return result;}private boolean isAjaxRequest(HttpServletRequest request) {String header = request.getHeader("X-Requested-With");if (header != null && "XMLHttpRequest".equals(header))return true;elsereturn false;}/** * Handles the logging of the exception. *  * @param e *            the exception to log. */protected void handleLogging(Exception e) {if (logCategory != null) {if (categoryLogger == null) {// init category loggercategoryLogger = LoggerFactory.getLogger(logCategory);}doLog(categoryLogger, e);} else {doLog(LOG, e);}}/** * Performs the actual logging. *  * @param logger *            the provided logger to use. * @param e *            the exception to log. */protected void doLog(Logger logger, Exception e) {if (logLevel == null) {logger.debug(e.getMessage(), e);return;}if ("trace".equalsIgnoreCase(logLevel)) {logger.trace(e.getMessage(), e);} else if ("debug".equalsIgnoreCase(logLevel)) {logger.debug(e.getMessage(), e);} else if ("info".equalsIgnoreCase(logLevel)) {logger.info(e.getMessage(), e);} else if ("warn".equalsIgnoreCase(logLevel)) {logger.warn(e.getMessage(), e);} else if ("error".equalsIgnoreCase(logLevel)) {logger.error(e.getMessage(), e);} else if ("fatal".equalsIgnoreCase(logLevel)) {logger.fatal(e.getMessage(), e);} else {throw new IllegalArgumentException("LogLevel [" + logLevel+ "] is not supported");}}protected String findResultFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) {String result = null;// Check for specific exception mappings.if (exceptionMappings != null) {int deepest = Integer.MAX_VALUE;for (Object exceptionMapping : exceptionMappings) {ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) exceptionMapping;int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t);if (depth >= 0 && depth < deepest) {deepest = depth;result = exceptionMappingConfig.getResult();}}}return result;}/** * Return the depth to the superclass matching. 0 means ex matches exactly. * Returns -1 if there's no match. Otherwise, returns depth. Lowest depth * wins. *  * @param exceptionMapping *            the mapping classname * @param t *            the cause * @return the depth, if not found -1 is returned. */public int getDepth(String exceptionMapping, Throwable t) {return getDepth(exceptionMapping, t.getClass(), 0);}private int getDepth(String exceptionMapping, Class exceptionClass,int depth) {if (exceptionClass.getName().contains(exceptionMapping)) {// Found it!return depth;}// If we've gone as far as we can go and haven't found it...if (exceptionClass.equals(Throwable.class)) {return -1;}return getDepth(exceptionMapping, exceptionClass.getSuperclass(),depth + 1);}/** * Default implementation to handle ExceptionHolder publishing. Pushes given * ExceptionHolder on the stack. Subclasses may override this to customize * publishing. *  * @param invocation *            The invocation to publish Exception for. * @param exceptionHolder *            The exceptionHolder wrapping the Exception to publish. */protected void publishException(ActionInvocation invocation,ExceptionHolder exceptionHolder) {invocation.getStack().push(exceptionHolder);}}
这里说明下,如果是出现异常,而且是ajax请求的话,就找JsonHandlerException这个异常所对应的视图:

<!-- 定义全局视图 --><global-results><result name="login" type="redirectAction">login</result><result name="404">/WEB-INF/view/404.jsp</result><result name="500">/WEB-INF/view/500.jsp</result><result name="json_500" type="json"><param name="root">dataMap</param></result><result type="json"><param name="root">dataMap</param></result><!-- ajax请求的返回视图 --></global-results><!-- 定义全局异常--><global-exception-mappings><exception-mapping result="500" exception="java.lang.Exception"/><exception-mapping result="json_500" exception="com.hatch.common.JsonHandlerException"/></global-exception-mappings>...

下面是自定义Json异常类

package com.hatch.common;public class JsonHandlerException extends Exception {/** *  */private static final long serialVersionUID = -4788951533205831941L;public JsonHandlerException() {super();}public JsonHandlerException(String message) {super(message);}public JsonHandlerException(String message, Throwable cause) {super(message, cause);}public JsonHandlerException(Throwable cause) {super(cause);}}
这样在页面一端,就可以正确的获取异常数据了。

对于普通的$.post请求,这个异常数据很容易可以人性化的提示给用户,这里用的easyui,可以在数据表格加载时,验证下有没有返回数据:

$('#dg').datagrid({striped : true,rownumbers : true,singleSelect : false,pagination : true,pageSize : 10,fitColumn : true,dataType : 'json',animate : true,loadMsg : '请稍候...',        url:'${ctx }/sys/user/doList', loadFilter:function(data){if(!data.rows||!data.total){if(data.msg){$.messager.alert('错误提示','操作失败!错误原因:<hr/>'+data.msg,'error');}else{$.messager.alert('错误提示','操作失败!','error');}return {total:0,rows:[]};}},        columns:[[  {field:'ck',checkbox:true,align:'center'},                  {title:'序号',field:'id',align:'center'},                  {title:'登录名',field:'username',align:'center'},                  {title:'名称',field:'name',align:'center'},                  {title:'性别',field:'gender',align:'center',formatter:function(v){ return v==1?'男':'女' }},                  {title:'手机',field:'phoneNumber',align:'center'},                  {title:'email',field:'email',align:'center'},                  {title:'所属部门',field:'department',align:'center',formatter:function(v){if(v)return v['name'];}},                  {title:'操作',field:'Operation',align:'center',formatter: operationFormate}                 ]],     });

以上红色字体表示数据加载异常时,提示给用户错误信息,效果如下:

当然,如果想做一致的处理,像默认的拦截器那样定位到一个错误页面,可以在这里加跳转信息:

loadFilter:function(data){if(!data.rows||!data.total){if(data.msg){$.messager.alert('错误提示','操作失败!错误原因:<hr/>'+data.msg,'error');}else{$.messager.alert('错误提示','操作失败!','error');}window.location = '${ctx}/jsonHandlerAction'return {total:0,rows:[]};}},
这样,又能跳转到我们默认的错误页面了:

这个错误信息,用了一个很笨的方法传递到错误页面,即在拦截器捕获到这个ajax操作的异常时 ,将这个异常信息加入到会话中,然后在js跳转后,在错误页面中取出错误信息。

至此,该方案介绍完毕,有更好方法的童鞋可以赐教!


原创粉丝点击