`

springMVC对异常处理的支持

阅读更多

无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了。跟其他MVC框架一样,springMVC也有自己的异常处理机制。
springMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,当然这也包括使用Spring已经为我们提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,另一种是使用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler。

 

 

 

1、实现自己的HandlerExceptionResolver,HandlerExceptionResolver是一个接口,springMVC本身已经对其有了一个自身的实现——DefaultHandlerExceptionResolver,该解析器只是对其中的一些比较典型的异常进行了拦截,然后返回对应的错误码,当然你也可以继承DefaultHandlerExceptionResolver类,然后重写其中的一些异常处理方法来实现自己的异常处理。

Java代码  收藏代码
  1. import javax.servlet.http.HttpServletRequest;  
  2. import javax.servlet.http.HttpServletResponse;  
  3.   
  4. import org.springframework.web.servlet.HandlerExceptionResolver;  
  5. import org.springframework.web.servlet.ModelAndView;  
  6.   
  7. public class ExceptionHandler implements HandlerExceptionResolver {  
  8.   
  9.     @Override  
  10.     public ModelAndView resolveException(HttpServletRequest request,  
  11.             HttpServletResponse response, Object handler, Exception ex) {  
  12.         // TODO Auto-generated method stub  
  13.         return new ModelAndView("exception");  
  14.     }  
  15.   
  16. }  

 上述的resolveException的第4个参数表示对哪种类型的异常进行处理。因为Exception类是所有异常类的基类,所以如果想根据异常类型的不同来进行不同的处理的话,可以在resolveException方法里面根据不同的异常类型进行不同的处理,返回不同的异常视图。如:

Java代码  收藏代码
  1. public class ExceptionHandler implements HandlerExceptionResolver {  
  2.   
  3.     @Override  
  4.     public ModelAndView resolveException(HttpServletRequest request,  
  5.             HttpServletResponse response, Object handler, Exception ex) {  
  6.         // TODO Auto-generated method stub  
  7.         if (ex instanceof NumberFormatException) {  
  8.             //doSomething...  
  9.             return new ModelAndView("number");  
  10.         } else if (ex instanceof NullPointerException) {  
  11.             //doSomething...  
  12.             return new ModelAndView("null");  
  13.         }  
  14.         return new ModelAndView("exception");  
  15.     }  
  16.   
  17. }  

 

 

定义了这样一个异常处理器之后就要在applicationContext中定义这样一个bean对象,如:

Xml代码  收藏代码
  1. <bean id="exceptionResolver" class="com.tiantian.xxx.web.handler.ExceptionHandler"/>  

Spring除了实现了一个DefaultHandlerExceptionResolver之外,还实现了一个SimpleMappingExceptionResolver,这两者都是继承自抽象类AbstractHandlerExceptionResolver,而AbstractHandlerExceptionResolver是实现了HandlerExceptionResolver接口的resolveException方法的,并由此抽取出两个抽象方法,一个是在进行异常处理之前执行的方法prepareResponse(exception, response),一个是进行异常解析的doResolveException(request, response, handler, exception)方法。SimpleMappingExceptionResolver,顾名思义就是通过简单的映射关系来决定由哪个视图来处理当前的错误信息。SimpleMappingExceptionResolver提供了通过异常类型exceptionMappings来进行异常与视图之间的映射关系,提供了在发生异常时通过statusCodes来映射异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时就返回defaultErrorView定义的视图,defaultErrorCode表示在发生异常时当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时默认返回的返回码。在使用SimpleMappingExceptionResolver时,当发生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默认值exception。

 

以下是一个简单的例子:

 

(1)SpringMVC的servlet配置文件中申明一个SimpleMappingExceptionResolver bean,并通过配置属性exceptionMappings和defaultExceptionView来指定异常和视图的对应关系。

Xml代码  收藏代码
  1. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  2.     <property name="exceptionMappings">  
  3.         <props>  
  4.             <prop key="NumberFormatException">number</prop><!-- 表示当抛出NumberFormatException的时候就返回名叫number的视图 -->  
  5.             <prop key="NullPointerException">null</prop>  
  6.         </props>  
  7.     </property>  
  8.     <property name="defaultErrorView" value="exception"/><!-- 表示当抛出异常但没有在exceptionMappings里面找到对应的异常时 返回名叫exception的视图-->  
  9.     <property name="statusCodes"><!-- 定义在发生异常时视图跟返回码的对应关系 -->  
  10.         <props>  
  11.             <prop key="number">500</prop><!-- 表示在发生NumberFormatException时返回视图number,然后这里定义发生异常时视图number对应的HttpServletResponse的返回码是500 -->  
  12.             <prop key="null">503</prop>  
  13.         </props>  
  14.     </property>  
  15.     <property name="defaultStatusCode" value="404"/><!-- 表示在发生异常时默认的HttpServletResponse的返回码是多少,默认是200 -->  
  16. </bean>  

(2)如下访问:

Java代码  收藏代码
  1. @Controller  
  2. @RequestMapping("/test")  
  3. public class TestController {  
  4.   
  5.     @RequestMapping("/null")  
  6.     public void testNullPointerException() {  
  7.         Blog blog = null;  
  8.         //这里就会发生空指针异常,然后就会返回定义在SpringMVC配置文件中的null视图  
  9.         System.out.println(blog.getId());  
  10.     }  
  11.       
  12.     @RequestMapping("/number")  
  13.     public void testNumberFormatException() {  
  14.         //这里就会发生NumberFormatException,然后就会返回定义在SpringMVC配置文件中的number视图  
  15.         Integer.parseInt("abc");  
  16.     }  
  17.       
  18.     @RequestMapping("/default")  
  19.     public void testDefaultException() {  
  20.         if (1==1)  
  21.             //由于该异常类型在SpringMVC的配置文件中没有指定,所以就会返回默认的exception视图  
  22.             throw new RuntimeException("Error!");  
  23.     }  
  24.       
  25. }  

 

(3)Jsp页面中可以访问到的异常对象,这里以NumberFormatException的返回视图number.jsp作为示例:

Jsp代码  收藏代码
  1. <%@ page language="java" import="java.util.*" pageEncoding="GB18030" isErrorPage="true"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'number.jsp' starting page</title>  
  13.       
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!--  
  20.     <link rel="stylesheet" type="text/css" href="styles.css">  
  21.     -->  
  22.   
  23.   </head>  
  24.     
  25.   <body>  
  26.     NumberFormatException. <br>  
  27.     <%=exception.getMessage() %><br/>  
  28.     <%=exception %><br/><span style="color: #3366ff;"><!-- 这是JSP中的内置对象exception --></span>  
  29.   
  30.   
  31.   
  32.     <%=request.getAttribute("ex") %><br><span style="color: #3366ff;"><!-- 这是SpringMVC放在返回的Model中的异常对象 --></span>  
  33.   
  34.   
  35.   
  36.     <%=request.getAttribute("javax.servlet.error.status_code") %><span style="color: #3366ff;"><!-- HttpServletResponse返回的错误码信息,因为前面已经配置了NumberFormatException的错误码返回值为888,所以这里应该显示888 --></span>  
  37.   
  38.   
  39.   
  40.   </body>  
  41. </html>  

   

(4)当请求/test/number.do的时候会返回定义好的number视图,返回结果如下:


 

2、使用@ExceptionHandler进行处理

 

使用@ExceptionHandler进行处理有一个不好的地方是进行异常处理的方法必须与出错的方法在同一个Controller里面

 

如:

Java代码  收藏代码
  1. import org.springframework.stereotype.Controller;  
  2. import org.springframework.web.bind.annotation.ExceptionHandler;  
  3. import org.springframework.web.bind.annotation.RequestMapping;  
  4.   
  5. import com.tiantian.blog.web.servlet.MyException;  
  6.   
  7. @Controller  
  8. public class GlobalController {  
  9.   
  10.       
  11.     /** 
  12.      * 用于处理异常的 
  13.      * @return 
  14.      */  
  15.     @ExceptionHandler({MyException.class})  
  16.     public String exception(MyException e) {  
  17.         System.out.println(e.getMessage());  
  18.         e.printStackTrace();  
  19.         return "exception";  
  20.     }  
  21.       
  22.     @RequestMapping("test")  
  23.     public void test() {  
  24.         throw new MyException("出错了!");  
  25.     }  
  26.       
  27.       
  28. }  

 这里在页面上访问test方法的时候就会报错,而拥有该test方法的Controller又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用

 

 

 

 

 

优先级

既然在SpringMVC中有两种处理异常的方式,那么就存在一个优先级的问题:

 

当发生异常的时候,SpringMVC会如下处理:

(1)SpringMVC会先从配置文件找异常解析器HandlerExceptionResolver

(2)如果找到了异常异常解析器,那么接下来就会判断该异常解析器能否处理当前发生的异常

(3)如果可以处理的话,那么就进行处理,然后给前台返回对应的异常视图

(4)如果没有找到对应的异常解析器或者是找到的异常解析器不能处理当前的异常的时候,就看当前的Controller中有没有提供对应的异常处理器,如果提供了就由Controller自己进行处理并返回对应的视图

(5)如果配置文件里面没有定义对应的异常解析器,而当前Controller中也没有定义的话,那么该异常就会被抛出来。

分享到:
评论

相关推荐

    springmvc对json支持

    总结起来,Spring MVC对JSON的支持主要依赖于Jackson库,通过`@ResponseBody`和`@RequestBody`注解实现数据交换,配合注解进行类型转换控制,同时允许开发者自定义序列化和反序列化行为,以及配置错误处理机制。...

    SpringMVC统一异常处理三种方法详解

    这篇文章主要介绍了SpringMVC-统一异常处理三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在 Spring MVC 应用的开发中,不管是对底层数据库操作...

    燕青老师springmvc的课堂教案

    11. **异常处理**:SpringMVC提供了一种优雅的异常处理机制,通过@ControllerAdvice和@ExceptionHandler注解,可以全局处理特定类型的异常。 12. **上传下载**:SpringMVC支持文件的上传和下载,通过MultipartFile...

    SpringMVC学习编程代码

    总的来说,"SpringMVC学习编程代码"提供的资源包括了SpringMVC的核心概念和实际应用,如配置文件、Controller、视图解析、数据绑定、异常处理以及拦截器的使用。通过这个项目,开发者可以深入理解SpringMVC的工作...

    SpringMVC完整使用教程

    SpringMVC 提供了统一的异常处理机制,可以通过 `@ExceptionHandler` 注解定义异常处理器,或配置 `HandlerExceptionResolver` 实现类来集中处理异常。 ### 第 7 章 数据验证 SpringMVC 结合 Hibernate Validator ...

    springmvc 3.2.8 restful支持

    8. **异常处理**:Spring MVC提供了全局异常处理机制,通过`@ControllerAdvice`和`@ExceptionHandler`注解,可以集中处理异常并返回自定义的错误响应。 在实际开发中,结合以上知识,我们可以构建一个完整的RESTful...

    SpringMVCC.zip

    13. **异常处理**: - 可以通过@ControllerAdvice和@ExceptionHandler全局处理异常,提高代码的可读性和可维护性。 14. **RESTful API支持**: - SpringMVC支持创建RESTful服务,通过@RequestMapping的GET、POST...

    springmvc框架源码.zip

    9. **异常处理**:SpringMVC提供了一套优雅的异常处理机制,允许开发者定义全局和特定异常的处理策略。 10. **参数绑定**:自动将请求参数绑定到控制器方法的参数上,支持基本类型、复杂类型以及自定义类型转换器。...

    springMVC练手代码

    10. **异常处理**:通过`@ExceptionHandler`注解,可以在控制器中统一处理异常,或者在配置文件中全局定义异常处理器。 通过这个练手代码,你可以实践上述概念,了解它们如何协同工作。同时,你还能学习如何集成...

    SpringMVC5.0jar包集合

    4. **改进的异常处理**:SpringMVC 5.0提供了更好的全局异常处理机制,你可以通过定义`@ControllerAdvice`类来集中处理异常,使代码更加整洁。 5. **WebSocket支持**:SpringMVC 5.0加强了WebSocket的支持,通过`@...

    尚硅谷SpringMVC部分全套教学文档笔记

    - SpringMVC通过@ControllerAdvice和@ExceptionHandler注解实现全局异常处理。 - 可以定义一个全局的异常处理器,处理所有Controller中抛出的异常,提供统一的错误页面或JSON响应。 通过以上知识点的学习,读者...

    SpringMVC框架架构介绍

    通过定义@ControllerAdvice和@ExceptionHandler注解,可以实现全局异常处理,捕获并处理所有Controller中的未捕获异常。 七、记录异常到日志: 结合日志框架(如Log4j或SLF4J),在全局异常处理中记录异常信息。 ...

    springmvc实战项目sample

    可以通过`@ExceptionHandler`注解自定义全局异常处理,或者配置`&lt;exception-type&gt;`标签处理特定异常。 7. **视图技术** SpringMVC支持多种视图技术,如JSP、FreeMarker、Thymeleaf等,可以根据项目需求选择合适的...

    SpringMVC Demo_java_springmvc_DEMO_

    7. **异常处理**:SpringMVC允许自定义全局或特定异常处理器,可以捕获和处理程序运行时可能出现的异常,将其转换为适当的HTTP响应。 8. **国际化与本地化**:SpringMVC支持多语言环境,通过资源文件配置,可以提供...

    SpringMVC+Mysql实例详解

    SpringMVC提供了异常处理机制,可以自定义异常处理器。使用LocaleResolver和MessageSource实现多语言支持。安全方面,Spring Security提供了一套完整的解决方案,包括身份验证、授权和CSRF防护。 总的来说,...

    SpringMVC详解

    SpringMVC提供了优雅的异常处理机制,允许开发者定义全局或特定Controller的异常处理器,将异常信息转换为用户友好的错误页面。 10. **SpringMVC的新特性** 随着版本的更新,SpringMVC不断引入新的特性和改进,...

    springMVC教案.rar

    7. **异常处理**: SpringMVC允许定义全局或特定类型的异常处理器,通过@ControllerAdvice和@ExceptionHandler注解实现。 8. **视图解析**: 视图解析器如InternalResourceViewResolver,负责根据视图名查找实际...

    springmvc 框架

    - **异常处理**:SpringMVC提供了全局异常处理机制,通过`@ExceptionHandler`注解,可以集中处理各种异常情况。 - **拦截器**:可以自定义拦截器,实现登录检查、权限控制等功能。 - **文件上传与下载**:...

    easyui分页、springmvc后台处理分页

    本项目重点介绍了如何结合EasyUI前端框架和SpringMVC后端框架实现高效的分页处理。下面将详细阐述相关知识点。 首先,EasyUI是一个基于jQuery的UI组件库,提供了丰富的界面元素,如表格、表单、分页等,使得开发者...

Global site tag (gtag.js) - Google Analytics