1、HandlerExceptionResolver

Spring HandlerExceptionResolver的实现们会处理controller执行过程中发送的unexpected exceptions。

一个HandlerExceptionResolver类似于你这web.xml中定义的exception mappings。然而,它们提供了更具弹性的方式。例如,它们提供了抛出exception时正在执行的handler的信息。更多地,编码式处理exceptions给予你更多的选择,可以在request被forwarded到另一个URL之前进行合适的处理。

除了实现HandlerExceptionResolver接口(具体来说就是实现resolveException(Exception, Handler) 方法,返回一个ModelAndView )外,你还可以使用SimpleMappingExceptionResolver或者创建@ExceptionHandler methods。前者可以让你获取可能被抛出的任意exception的class name,并将其映射到一个view name。其功能等效于Servlet API中的exception mapping feature,但可以实现更细化的exceptions mappings (来自不同handlers)。@ExceptionHandler注解可被用于methods,会被调用来处理一个exception。 这种方法可以定义在@Controller内部,或者定义在@ControllerAdvice class内--这样会适用于很多@Controller classes。 后面会详述。

2、@ExceptionHandler

HandlerExceptionResolver接口和SimpleMappingExceptionResolver实现们允许你声明式地将Exceptions映射到特定的views -- 还可以在forward到这些views之前进行一些逻辑操作。然而,在某些情况下,特别是在依赖于@ResponseBody methods而不是view resolution时,直接设置response status、将error content写入response body更为方便。

你可以使用@ExceptionHandler methods来完成。 当在一个controller内部声明了这种方法后,这种方法就会被用于该controller(或任意子类)中@RequestMapping methods抛出的exceptions。你也可以在一个@ControllerAdvice class中定义一个@ExceptionHandler method,这种情况下I安,他会处理很多controllers的@RequestMapping methods抛出的异常。

下面是controller本地的@ExceptionHandler method:

@Controller
public class SimpleController { // @RequestMapping methods omitted ... @ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex) {
// prepare responseEntity
return responseEntity;
} }

注意,@ExceptionHandler的value可以是Exception类型的数组。只要被抛出的异常匹配了该数组中的任意一个,该方法就会被调用。如果该注解的value没有被设置,那么异常类型就是方法的参数类型。

很像标准controller 的@RequestMapping methods,@ExceptionHandler methods的方法参数和返回值是很灵活的。 例如,在Servlet环境下可以使用HttpServletRequest,而在Porlet环境下可以使用PortletRequest。 返回类型可以是String -- 会被解释成view name,也可以是ModelAndView对象、ResponseEntity,或者使用@ResponseBody将返回值转成String并写入response stream。

3、处理标准的Spring MVC Exceptions

在处理一个请求时,Spring MVC 可能抛出大量异常。 SimpleMappingExceptionResolver 可以轻易地将任何异常按照需要映射到默认的error view。然而,当clients以自动方式解析响应时,你会希望设置特定的response status code。 这些状态码可以区分client error (4xx) 或 server error (5xx)。

DefaultHandlerExceptionResolver 会将Spring MVC exceptions 翻译成特定的error status codes。 MVC namespace、MVC Java  config、还有DispatcherServlet(当不使用MVC namespace 或 Java config时)会默认注册该功能。

下面列出了一些由该resolver处理的exceptions和相应的status code。

Exception HTTP Status Code

BindException

400 (Bad Request)

ConversionNotSupportedException

500 (Internal Server Error)

HttpMediaTypeNotAcceptableException

406 (Not Acceptable)

HttpMediaTypeNotSupportedException

415 (Unsupported Media Type)

HttpMessageNotReadableException

400 (Bad Request)

HttpMessageNotWritableException

500 (Internal Server Error)

HttpRequestMethodNotSupportedException

405 (Method Not Allowed)

MethodArgumentNotValidException

400 (Bad Request)

MissingPathVariableException

500 (Internal Server Error)

MissingServletRequestParameterException

400 (Bad Request)

MissingServletRequestPartException

400 (Bad Request)

NoHandlerFoundException

404 (Not Found)

NoSuchRequestHandlingMethodException

404 (Not Found)

TypeMismatchException

400 (Bad Request)

DefaultHandlerExceptionResolver 会悄悄的工作:设置response的status code。然而,它没有将任何error content写入到response body 的功能-- 当你希望给每个error response添加一些开发者友好的内容时,它无能为力。这时,你可以准备一个ModelAndView,然后通过view resolution来render content -- 就是说,通过配置一个ContentNegotiatingViewResolver、MappingJackson2JsonView等等view resolution来完成。然而,你可能更倾向于使用@ExceptionHandler method。

如果你倾向于使用@ExceptionHandler methods来写入error content,你可以继承ResponseEntityExceptionHandler。这对于需要提供一个@ExceptionHandler method来处理标准的Spring MVC exceptions并返回ResponseEntity的@ControllerAdvice classes来说,是一个很方便的base。它可以允许你定制response,并通过message converter来写入error content。 详见其javadocs。

4、使用@ResponseStatus来注解业务异常 (Business Exceptions)

业务异常可以使用@ResponseStatus来注解。 当该异常被抛出时,ResponseStatusExceptionResolver会设置其response status。 DispatcherServlet默认注册了ResponseStatusExceptionResolver,所以直接可用。

5、定制Default Servlet Container Error page

当response status被设置成一个error status code,且response body为空时,Servlet Container通常会render一个HTML格式的error page。想要定制container默认的error page,你可以在web.xml中声明一个<error-page>元素。一直到Servlet 3 (不包含),该元素都是被映射到一个特定的status code或exception type。但从Servlet 3 开始,error page不需要被映射了,这意味着指定的位置会定制默认的Servlet Container error page。

<error-page>
<location>/error</location>
</error-page>

注意,该error page的实际位置可以是一个JSP page,或者container包含的其他URL -- 只要是通过一个@Controller method处理的URL即可:

当写入error information时,可以之一个controller中通过request attributes来访问HttpServletResponse中设置好的status code和error message:

@Controller
public class ErrorController { @RequestMapping(path = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Map<String, Object> handle(HttpServletRequest request) { Map<String, Object> map = new HashMap<String, Object>();
map.put("status", request.getAttribute("javax.servlet.error.status_code"));
map.put("reason", request.getAttribute("javax.servlet.error.message")); return map;
} }

或者,在一个JSP中:

<%@ page contentType="application/json" pageEncoding="UTF-8"%>
{
status:<%=request.getAttribute("javax.servlet.error.status_code") %>,
reason:<%=request.getAttribute("javax.servlet.error.message") %>
}

官方文档连接:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

Spring 4 官方文档学习(十一)Web MVC 框架之异常处理的更多相关文章

  1. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  2. Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图

    接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolv ...

  3. Spring 4 官方文档学习(十一)Web MVC 框架

    介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...

  4. Spring 4 官方文档学习(十二)View技术

    关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...

  5. Spring Boot 官方文档学习(一)入门及使用

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  6. Spring boot官方文档学习(一)

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  7. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)

    接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...

  8. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

  9. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)

    题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...

  10. Spring 4 官方文档学习(十一)Web MVC 框架之编码式Servlet容器初始化

    在Servlet 3.0+ 环境中,你可以编码式配置Servlet容器,用来代替或者结合 web.xml文件.下面是注册DispatcherServlet : import org.springfra ...

随机推荐

  1. Oracle正确删除archivelog文件(转)

    from:http://www.itpub.net/thread-1636118-6-1.html Oracle在开启了归档模式后,会在指定的archive目录下产生很多的archivelog文件,而 ...

  2. NeHe OpenGL教程 第四十七课:CG顶点脚本

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. winXP下安装opensshd服务

    1)参考如下帖子:http://blog.chinaunix.net/uid-23187544-id-2527564.html http://wuhuizhong.iteye.com/blog/122 ...

  4. 源码解读—HashTable

    在上一篇学习过HashMap(源码解读—HashMap)之后对hashTable也产生了兴趣,随即便把hashTable的源码看了一下.和hashMap类似,但是也有不同之处. public clas ...

  5. host DNS 访问规则

    昨天站点一直出现302循环重定向问题,捣鼓了半天才解决,原来是hosts和dns配置问题. 注:当你的站点出现循环重定向时,首先应该关注的hosts以及dns配置,确保无误. 下面记录下相关知识点: ...

  6. Squid服务日志分析

    Squid服务日志分析 Apache 和 Squid 是两种著名的代理缓存软件,但Squid 较 Apache 而言是专门的代理缓存服务器软件,其代理缓存的功能强大,支持 HTTP/1.1 协议,其缓 ...

  7. 41. 这张表lbdeveloplog可以查看各个对象的提交情况,包括是哪个IP提交的

    lbdeveloplog 这张表lbdeveloplog可以查看各个对象的提交情况,包括是哪个IP提交的

  8. notepad++ 正则表达式

    body { font-family: Bitstream Vera Sans Mono; font-size: 11pt; line-height: 1.5; } html, body { colo ...

  9. MySQL_财务统计各产品品类各城市上周收入毛利表_20161202

    注:财务需要统计各产品品类各城市上周毛利情况 下面这样的表是沟通后展现的形式.数据展现形式我认为的大都是行列转 列转行的转置 从财务角度这样展现形式比较适合. 由于黄色部分为汇总项目,因此我拆分成9个 ...

  10. 关于c#中的console用法大全

    C#之Console   Console.Write  表示向控制台直接写入字符串,不进行换行,可继续接着前面的字符写入.Console.WriteLine  表示向控制台写入字符串后换行.Conso ...