spring3.0异常处理进阶

标签: spring3 异常处理 | 发表时间:2015-03-01 23:03 | 作者:baalwolf
出处:http://www.iteye.com

spring3.0开发不可避免要遇到异常处理,如果只有jsp请求能捕获到异常,是不足够的, 有时候AJAX返回json数据时遇到异常。这时候默认的处理方式不能满足了, 需要自定义的方式支持同步和ajax异步异常处理。

 

 或许大家都知道spring3的异常处理方法有:

1   以配置文件的方式进行异常管理

在配置dispacher-servlet.xml

 

[xhtml]  view plain copy
 
  1. <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  2.   
  3.     <property name="defaultErrorView">  
  4.       <value>jsonView</value>  
  5.     </property>  
  6.    <property name="exceptionMappings">  
  7.       <props>  
  8.     <prop key="java.lang.Exception">/common/error.jsp</prop>     
  9.       </props>   
  10.     </property>  
  11.   </bean>  

 

配置多个异常处理的地方

 

2  以注解的方式配置异常管理

 为了方便阅读, 把代码的地方发全一点

 

[java]  view plain copy
 
  1. @Controller  
  2. public class ExceptionHandlerController  
  3. {  
  4.     private final Logger log = LoggerFactory.getLogger(getClass());  
  5.       
  6.     @ExceptionHandler(ManagerSecurityException.class)  
  7.     public ModelAndView handleManagerSecurityException(ManagerSecurityException e,  
  8.             HttpServletResponse response)  
  9.     throws IOException  
  10.     {  
  11.         log.info("Manager exception handler " + e.getMessage());  
  12.           
  13.         response.sendError(HttpServletResponse.SC_FORBIDDEN,  
  14.             e.getMessage());  
  15.          return new ModelAndView("viewName",new HashMap());  
  16.     }  
  17. }  

 

这样的配置处理jstl请求jsp没有问题, 

如果是jquery的 $.post的方法请求, 那么如果还是返回   error.jsp  , 那在  js的success函数里则不能很好地输出显示了。

 

问题又来了:  如果在 handleManagerSecurityException方法的上面打上注解 @ResponeBody

那么这样又只能返回 json格式串的异常处理, 你想同步请求跳到到error.jsp又不行啦!

 

解决办法是这样的:定制化异常处理

 

 

[xhtml]  view plain copy
 
  1. <bean id="exceptionResolver" class="com.wsd.core.web.servlet.handle.CustomSimpleMappingExceptionResolver">  
  2.         <property name="defaultErrorView">  
  3.             <value>/common/error.jsp</value>  
  4.         </property>  
  5.     <property name="exceptionMappings">  
  6.         <props>  
  7.             <prop key="java.lang.Exception">/common/error.jsp</prop>     
  8.         </props>   
  9.     </property>  
  10.     </bean>  

 

 

下面我们来看看CustomSimpleMappingExceptionResolver.java是如何做到支持JSP和JSON格式返回的异常错误的

 

 

[java]  view plain copy
 
  1. @Override  
  2. protected ModelAndView doResolveException(HttpServletRequest request,  
  3.         HttpServletResponse response,  
  4.         Object handler,  
  5.         Exception ex) {  
  6.   
  7.     // Expose ModelAndView for chosen error view.  
  8.     String viewName = determineViewName(ex, request);  
  9.     if (viewName != null) {//JSP格式返回  
  10.         if(!(request.getHeader("accept").indexOf("application/json")>-1 || request.getHeader("X-Requested-With").indexOf("XMLHttpRequest")>-1)){//如果不是异步请求  
  11.             // Apply HTTP status code for error views, if specified.  
  12.             // Only apply it if we're processing a top-level request.  
  13.             Integer statusCode = determineStatusCode(request, viewName);  
  14.             if (statusCode != null) {  
  15.                 applyStatusCodeIfPossible(request, response, statusCode);  
  16.                 return getModelAndView(viewName, ex, request);  
  17.             }  
  18.         }else{//JSON格式返回  
  19.             Map<String, Object> model=new HashMap<String, Object>();  
  20.             if(this.logger.isDebugEnabled()){  
  21.                 model.put("debug", true);   
  22.             }//exception  
  23.             model.put(ConfigConstants.RESULT, ex.getMessage());  
  24.             model.put("failure", true);  
  25.             try {  
  26.                 response.getWriter().write("有异常啦!");  
  27.             } catch (IOException e) {  
  28.                 e.printStackTrace();  
  29.             }  
  30.             return new ModelAndView();  
  31.         }  
  32.         return null;  
  33.     }  
  34.     else {  
  35.         return null;  
  36.     }  
  37. }  

 

 

这里判断了request.getHeader("accept").indexOf("application/json")是不是异步请求

下面给出同步和异步请求的Header

同步的text/html

=== MimeHeaders ===
host = localhost:8888
user-agent = Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
accept = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language = en,zh;q=0.7,en-gb;q=0.3
accept-encoding = gzip,deflate
accept-charset = ISO-8859-1,utf-8;q=0.7,*;q=0.7
keep-alive = 115
connection = keep-alive
cookie = JSESSIONID=BB7441E4B481FF64A5BCC8E6F596C330

 

异步的application/json
=== MimeHeaders ===
host = localhost:8888
user-agent = Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
accept = application/json, text/javascript, */*
accept-language = en,zh;q=0.7,en-gb;q=0.3
accept-encoding = gzip,deflate
accept-charset = ISO-8859-1,utf-8;q=0.7,*;q=0.7
keep-alive = 115
connection = keep-alive
content-type = application/x-www-form-urlencoded
x-requested-with = XMLHttpRequest
referer =  http://localhost:8888/auth/auth/dictionary/dictionaryForm.html
cookie = JSESSIONID=A4B59EA87C9B83B71C0D455634746411

 

请注意

try {
     response.getWriter().write("有异常啦!");
    } catch (IOException e) {
     e.printStackTrace();
    }
    return new ModelAndView();

 

关键就在最后这1句   return new ModelAndView();

为什么不写 return null;   或者  return new ModelAndView('jsonView', model); 呢?

 

因为spring3的源码里这样写着了

 

[java]  view plain copy
 
  1. protected ModelAndView processHandlerException(HttpServletRequest request,  
  2.         HttpServletResponse response,  
  3.         Object handler,  
  4.         Exception ex) throws Exception {  
  5.   
  6.     // Check registerer HandlerExceptionResolvers...  
  7.     ModelAndView exMv = null;  
  8.     for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {  
  9.         exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);  
  10.         if (exMv != null) {  
  11.             break;  
  12.         }  
  13.     }  
  14.     if (exMv != null) {  
  15.         if (exMv.isEmpty()) {  
  16.             return null;  
  17.         }  
  18.         if (logger.isDebugEnabled()) {  
  19.             logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv,  
  20.                     ex);  
  21.         }  
  22.         WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());  
  23.         return exMv;  
  24.     }  
  25.   
  26.     throw ex;  
  27. }  

 

 

注意看

  if (exMv != null) {
   if (exMv.isEmpty()) {
    return null;
   }

这句和最后一句:  throw ex;

 

如果你写 respone.getWriter().write("有异常啦");   你也要  new一个空的ModelAndView,

上面的代码表明, 如果你 return null;  它就跑出异常  throw ex;    如果没人接收, 则会调用你配置的默认异常处理器

或者中断不做任何输出。

 

好了, 这样可以同时支持同步和AJAX异步请求异常处理了。

 

下面附上截图, 以免误人子弟~

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [spring3 异常处理] 推荐:

Oracle 异常处理

- - 编程语言 - ITeye博客
使用RAISE_APPLICATION_ERROR存储过程. ============================================================ */ --演示该存储过程 BEGIN. RAISE_APPLICATION_ERROR(-20000, 'Account past due.');-- explicitly raise exception END; --创建子程序 CREATE OR REPLACE PROCEDURE account_status (.

剖析Spring3.x的“自动性”

- -
《剖析Spring3.x的“自动性”》. 其实这篇博文,只是有感而发,或者说是对之前博客(. 详解SSJ(Spring3.x mvc + Spring3.x Core + JPA2.x)轻量级集成开发目录汇总. )不全面或者遗漏的一种补充. 算了,不扯那么远了,直接进入正题. 二、自动装配时如果被装配的对象构造带参数怎么办.

spring mvc 异常处理(转)

- - 编程语言 - ITeye博客
链接:http://gaojiewyh.iteye.com/blog/1297746 (附源码). 链接:http://zywang.iteye.com/blog/983801 . 链接:http://www.cnblogs.com/xguo/p/3163519.html . 链接:http://fuliang.iteye.com/blog/947191 .

Oracle异常处理概念

- - Oracle - 数据库 - ITeye博客
5.1.1 预定义的异常处理. 5.1.2 非预定义的异常处理. 5.1.3 用户自定义的异常处理. 5.1.4  用户定义的异常处理. 5.2.1 在执行部分引发异常错误. 5.2.2 在声明部分引发异常错误. 5.3 异常错误处理编程. 5.4  在 PL/SQL 中使用 SQLCODE, SQLERRM异常处理函数.

Java异常处理策略

- - 研发管理 - ITeye博客
任务与预先设定的规则不相符的情况都可以称之为异常. 但凡业务逻辑操作,都会划定一些边界或规则,但是往往事与愿违,总会有调皮鬼来挑战系统的健壮性. 用户并不都是知道潜规则的,比如用户的银行账户中只有100块钱,但是用户不查询就直接取200块. 码农有时候太过自信了,比如你在编写文件下载功能时忽略了文件有可能不存在这个分支流程.

【javaScript基础】异常处理

- - CSDN博客Web前端推荐文章
         理解异常在javaScript面向对象编程是非常重要的,异常是一种非常强大的处理错误的方式.          首先我们来看一个有问题的代码:. 在以上这个例子中,访问一个不存在的变量,在这种情况下,程序会怎么处理. 很早以前的处理方式就是程序直接崩溃死掉,所以我们不能容忍这种处理方式,需要有办法来处理.

JVM中的异常处理

- - BlogJava-首页技术区
欢迎来到“ Under The Hood”第六期. 本期我们介绍 JVM处理异常的方式,包括如何抛出和捕获异常及相关的字节码指令. 但本文不会讨论finally子句,这是下期的主题. 你可能需要阅读 往期的文章才能更好的理解本文. 在程序运行时,异常让你可以平滑的处理意外状况. 为了演示JVM处理异常的方式,考虑NitPickyMath类,它提供对整数进行加,减,乘,除以及取余的操作.

spring3.0异常处理进阶

- - Web前端 - ITeye博客
spring3.0开发不可避免要遇到异常处理,如果只有jsp请求能捕获到异常,是不足够的, 有时候AJAX返回json数据时遇到异常. 这时候默认的处理方式不能满足了, 需要自定义的方式支持同步和ajax异步异常处理.  或许大家都知道spring3的异常处理方法有:. 1   以配置文件的方式进行异常管理.

异常处理的最佳实践

- - 博客 - 伯乐在线
译者注:这是一篇2003年的文章,因为时间久远,可能有些观点已经过时,但里面讨论的大部分方法如今仍能适用. 如若有其他好的错误处理的方法,欢迎留言. 异常处理的关键就在于知道何时处理异常以及如何使用异常. 这篇文章,我会提到一些最佳的异常处理方法. 我也会总结checked exception的用法.

Java异常处理的陋习展播

- - 博客 - 伯乐在线
注:本文来自志军(@ _Zhijun )在微博推荐的一篇转载于2007年09月27的旧文,他说“没法找到原作者”. 的确,我也花了半个多小时在找原作者. 先是找到了一个标注“2005年6月18日转字Java研究组织”的文章(“Java研究组织”的域名已过期),后来找到是大连理工大学碧海青天BBS上一个发于的2003年5月中旬的 合集帖子,其中提到一条来自 CSDN 的链接,可惜该链接已挂,否则应该能找到作者的.