Struts2、Spring MVC4 框架下的ajax统一异常处理

本文算是struts2 异常处理3板斧spring mvc4:异常处理 后续篇章,普通页面出错后可以跳到统一的错误处理页面,但是ajax就不行了,ajax的本意就是不让当前页面发生跳转,仅局部刷新,从而改善用户体验,基本思路是:把异常转换成json数据返回,这样ajax的回调函数,就能解析出错误原因。

 

一、如何区分ajax请求与普通请求

打开firefox的调试工具观察一下:

普通的页面请求

jquery发起的ajax请求

对比一下,可以发现jquery发生的ajax请求,Request Headers里多出了x-requested-with,用它就可以判断是否ajax请求。

 

二、struts2框架

a) 先定义一个ajax通用异常

 1 package com.cnblogs.yjmyzz.exception;
 2
 3 public class AjaxException extends Exception {
 4
 5     private static final long serialVersionUID = -8503861588580421151L;
 6
 7     public AjaxException(String message) {
 8         super(message);
 9     }
10
11 }

View Code

b) 然后修改异常拦截器

 1 package com.cnblogs.yjmyzz.interceptor;
 2 import javax.servlet.http.HttpServletRequest;
 3
 4 import org.apache.logging.log4j.*;
 5 import org.apache.struts2.ServletActionContext;
 6 import org.springframework.util.StringUtils;
 7 import com.cnblogs.yjmyzz.exception.AjaxException;
 8 import com.opensymphony.xwork2.*;
 9 import com.opensymphony.xwork2.interceptor.*;
10
11 public class ExceptionInterceptor extends AbstractInterceptor {
12
13     private static final long serialVersionUID = -6358803554282730952L;
14     Logger logger = LogManager.getLogger();
15
16     @Override
17     public String intercept(ActionInvocation ai) throws Exception {
18         String result = null;
19         try {
20             result = ai.invoke();
21         } catch (Exception e) {
22             logger.error(ai.toString(), e);
23             ai.getStack().push(new ExceptionHolder(e));
24             result = "error";
25
26             HttpServletRequest request = ServletActionContext.getRequest();
27             String xRequestedWith = request.getHeader("X-Requested-With");
28             if (!StringUtils.isEmpty(xRequestedWith)) {
29                 // ajax请求
30                 // 转换成ajax异常,并放入stack中
31                 ai.getStack().push(
32                         new ExceptionHolder(new AjaxException(e.getMessage())));
33                 result = "ajax-error";
34             }
35         }
36         return result;
37     }
38
39 }

View Code

c) 修改struts.xml文件

 1     <package name="base-default" extends="struts-default">
 2         <global-results>
 3             <result name="ajax-error">/WEB-INF/common/ajax-error.jsp</result>
 4             <result name="error">/WEB-INF/common/error.jsp</result>
 5         </global-results>
 6         <global-exception-mappings>
 7             <exception-mapping exception="com.cnblogs.yjmyzz.exception.AjaxException"
 8                 result="ajax-error" />
 9             <exception-mapping exception="java.lang.Exception"
10                 result="error" />
11         </global-exception-mappings>
12     </package>

View Code

即:返回ajax-error,异常类型为AjaxException,则交给/WEB-INF/common/ajax-error.jsp处理

d) ajax-error.jsp页面

1 <%@ page contentType="application/json;charset=UTF-8" language="java"%><%@ taglib prefix="s" uri="/struts-tags"%>{"error":"<s:property value="exception" />"}

View Code

即:如果出错,最终返回的是json串,类似:{"error":"com.cnblogs.yjmyzz.exception.AjaxException: / by zero"}

e) 然后调用ajax的地方

 1             $.ajax({
 2                 type:"GET",
 3                 url:"${pageContext.request.contextPath}/rest/orders/x",
 4                 success: function(data, textStatus, jqXHR){
 5                     if (data.error!=undefined){
 6                         alert("错误:" + data.error);
 7                         return false;
 8                     }
 9                     //正常处理
10                     alert("ajax请求成功!");
11                 },
12                 error: function(jqXHR, textStatus, errorThrown){
13                     alert('error: ' + textStatus);
14                 }
15             });

View Code

如果服务端出异常,则ajax调用完成后,会弹出异常信息,否则按正常流程处理

 

三、Spring MVC4

a) 先修改Controller基类里的异常处理方法

 1     @ExceptionHandler
 2     public String exp(HttpServletRequest request, Exception ex) {
 3         String resultViewName = "errors/error";
 4
 5         // 记录日志
 6         logger.error(ex.getMessage(), ex);
 7
 8         // 根据不同错误转向不同页面
 9         if (ex instanceof BusinessException) {
10             resultViewName = "errors/biz-error";
11         } else {
12             // 异常转换
13             ex = new Exception("系统太累了,需要休息!");
14         }
15         request.setAttribute("ex", ex);
16
17         String xRequestedWith = request.getHeader("X-Requested-With");
18         if (!StringUtils.isEmpty(xRequestedWith)) {
19             // ajax请求
20             resultViewName = "errors/ajax-error";
21
22         }
23
24         return resultViewName;
25     }

View Code

大致意思是,如果发现是ajax请求,则有异常,则交给"errors/ajax-error"视图处理

b) ajax-error.jsp页面

1 <%@ page contentType="application/json;charset=UTF-8" language="java"%><%Exception e = (Exception) request.getAttribute("ex");%>{"error":"<%=e.getClass().getSimpleName()%>","detail":"<%=e.getMessage()%>"}

View Code

c) 调用ajax的页面

 1             $.ajax({
 2                 type:"GET",
 3                 url:"${pageContext.request.contextPath}/common-exception",
 4                 success: function(d, textStatus, jqXHR){
 5                     if (d.error!=undefined){
 6                         alert("错误:" + d.detail);
 7                         return false;
 8                     }
 9                     //其它正常处理
10                     alert("ajax请求成功!");
11                 },
12                 error: function(jqXHR, textStatus, errorThrown){
13                     alert('error: ' + textStatus);
14                 }
15             });

View Code

如果服务端返回异常,ajax得到的反馈内容大概是:{"error":"Exception","detail":"系统太累了,需要休息!"}

时间: 2024-12-30 03:02:28

Struts2、Spring MVC4 框架下的ajax统一异常处理的相关文章

在Spring MVC框架下 一个@Repository的dao中 可以同时注入hibernateTemplate和jdbcTemplate吗

问题描述 在Spring MVC框架下 一个@Repository的dao中 因为感觉jdbc查询起来编码比较方便 所有想引入spring jdbc的东西 这时一个dao中想同时注入hibernateTemplate和jdbcTemplate 这样做可以吗 存在什么潜在的问题吗? 配置XML文件<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method=

spring-请问在Spring+Hibernate框架下连接两个数据库

问题描述 请问在Spring+Hibernate框架下连接两个数据库 两个数据库都是MySql的,一个在我本机,一个在我同事那,在ApplicationContext.xml里配两个DataSource,还需要配置哪些? 然后我在dao使用时怎么分别查询不同数据库的数据? 抱歉啊,新用户,没那个C币. 解决方案 http://blog.sina.com.cn/s/blog_454a9dc001012d6a.html 解决方案二: spring+hibernate下连接两个以上的数据库

spring mvc-Springmvc框架下的,关于数据库自增ID获取的问题

问题描述 Springmvc框架下的,关于数据库自增ID获取的问题 向数据库中插入新的数据.并且ID是设置为自增的,我该如何做到插入的同时还能够获取到这个数据的id呢 解决方案 http://blog.csdn.net/yaerfeng/article/details/7231093 解决方案二: 有一个selectkey的属性,加上就好了 解决方案三: 首先,先在数据库中设置其ID为自增 然后,往数据库中插入数据 再然后,根据所插入的一些信息查找出刚刚插入数据的ID 解决方案四: spring

zTree的调用设使用(跨两个系统,两类技术实现的项目案例SpringMVC+Spring+MyBatis和Struts2+Spring+ibatis框架组合)

1.从zTree官网上下载zTree的包,zTree的官方网址是:http://www.ztree.me/v3/main.php#_zTreeInfo 2.引入zTree所需的依赖,例如(jQuery的js自己引入): <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ include file="common/common.

spring mvc4:异常处理

前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理: 一.Servlet配置文件修改 1 <bean id="exceptionResolver" 2 class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 3 <property name="defaultErrorView" value=&quo

Spring框架下的单元测试方法

介绍在Spring的框架下,做单元测试的两种办法. 一.使用spring中对Junit框架的整合功能 除了junit4和spring的jar包,还需要spring-test.jar.引入如下依赖: <span style="font-size:18px;"><span style="white-space:pre">        </span><dependency> <groupId>org.sprin

easyui-struts2+spring+mybatis框架。 进入一个页面时,同时访问三个url会报错。

问题描述 struts2+spring+mybatis框架. 进入一个页面时,同时访问三个url会报错. 解决方案 这个应该是mybatis查询出错吧. 参数集合里面已经包含了count参数? 解决方案二: 这个是sql语句写错了,你把报错中的sql语句粘出来放数据库执行一下看看会不会报错 解决方案三: 你在controller重新写两个方法针对你上面的请求,你在页面刷新之前同时对page.action进行了访问,还传入了不同的查询条件和参数导致的.注意一下的onBeforeLoad:

thinkphp框架下实现登录、注册、找回密码功能_php技巧

本文实例为大家分享了thinkphp框架下使用ajax表单提交的登录.注册.找密码的实现方法,以及注册后的用户需后台审核. user表的字段为id.num.password.name.email.addtime.status 具体代码如下 <?php namespace Home\Controller; use Think\Controller; class LoginController extends Controller { //处理登录 public function signin(){

SSH集成框架下真正实现Spring AOP拦截功能

问题的提出: 在Struts1框架下,有三种类型的Action控制器,分别是MappingDispatchAction.DispatchAction和Action,他们是依次继承,最终执行的execute方法.但MappingDispatchAction.DispatchAction的子类中没有execute方法,只有参数指定的具体方法,而这些方法是被MappingDispatchAction.DispatchAction本类的execute方法调用执行,特别注意的是它是通过反射机制来做的(大家