Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2044|回复: 0
打印 上一主题 下一主题

Spring Boot Web应用的异常处理

[复制链接]

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
跳转到指定楼层
楼主
发表于 2017-8-3 14:42:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Web应用在处理请求时可能会出现多种错误,如请求参数不正确、URL不存在、请求方法错误、内部未知错误等。SpringMVC有多种异常处理方式,使用某种方式的判断标准是,你的异常是在请求处理的哪个阶段发生的。
在执行@RequestMapping方法时发生的异常
这也是最常见的异常了,处理业务逻辑时可能会发生各种问题,如数据库报错、请求参数格式错误/缺失/值非法等。此类异常的捕获方法有两种,对于提供RESTful服务的应用,使用@ControllerAdvice和@ExceptionHandler注解; 对于使用模板渲染HTML的应用,实现HandlerExceptionResolver接口。
先说说RESTful应用,由于返回的是JSON而不是页面,因此在异常处理方法中就不能返回ModelAndView对象(如果非要如此,也可以返回只包含一个JSON字符串的View)。一个典型的RESTful异常处理类如下:

  1. /**
  2. * 异常处理器。该类会处理所有在执行标有@RequestMapping注解的方法时发生的异常
  3. * Created by whf on 4/7/16.
  4. */
  5. @ControllerAdvice
  6. public class RestExceptionHandler extends ResponseEntityExceptionHandler {


  7.     /**
  8.      * 处理@RequestParam错误, 即参数不足
  9.      * @return
  10.      */
  11.     @Override
  12.     protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

  13.         return new ResponseEntity<>(new MatrixResponse(ErrorCode.ARG_INVALID), status);
  14.     }

  15.     /**
  16.      * 处理500错误
  17.      * @return
  18.      */
  19.     @Override
  20.     protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
  21.         //log.error("got internal error : {}", ex);

  22.         // 请求方式不支持
  23.         if (ex instanceof HttpRequestMethodNotSupportedException) {
  24.             return new ResponseEntity<>(new MatrixResponse(ErrorCode.REQUEST_METHOD_UNSUPPORTED), status);
  25.         }

  26.         return new ResponseEntity<>(new MatrixResponse(ErrorCode.INTERNAL_ERROR), status);
  27.     }


  28.     /**
  29.      * 处理参数类型转换失败
  30.      * @param request
  31.      * @return
  32.      */
  33.     @Override
  34.     protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
  35.         //log.error("type mismatch");

  36.         return new ResponseEntity<>(new MatrixResponse(ErrorCode.ARG_INVALID), status);
  37.     }
  38. }
复制代码
有人可能会问,@ExceptionHandler注解去哪了?要注意的是,SpringMVC为我们提供了一个通用的异常处理逻辑,即ResponseEntityExceptionHandler类,该类的handleException()方法上标注了@ExceptionHandler注解。此方法会判断 Exception 的类型,对于每一种类型,会交由对应的protected handleXXXX()方法处理,子类只需要重写对应的方法即可。
对于非RESTful应用,则需要返回一个View。这时使用HandlerExceptionResolver:

  1. @Component
  2. public class ExceptionHandler implements HandlerExceptionResolver {
  3.     private static Logger log = LoggerFactory.getLogger(ExceptionHandler.class);

  4.     @Autowired
  5.     private Mail mail;

  6.     @Override
  7.     public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) {
  8.     // 异常处理逻辑 goes here
  9.         log.info("got exception: {}", ex.getClass());

  10.         return new ModelAndView("pc/500");

  11.     }




  12. }
复制代码
从SpringMVC源码中可知,DispatcherServlet中如果产生了异常,则接下来会在processDispatchResult()方法中查询当前容器中是否有HandlerExceptionResolver接口的实现类,如果有则调用它的resolveException()方法,得到返回的View,如果没有则使用框架默认的异常处理类。

在执行@RequestMapping之前遇到的异常
该类异常通常是因为SpringMVC没有找到能处理当前请求的控制器造成的,比如最常见的404。此时@ControllerAdvice就不起作用了,因为@RequestMapping方法根本没找到,更不可能执行。此时我们要写一个@RestController,并实现ErrorController接口:

  1. @RestController
  2. public class FinalExceptionHandler implements ErrorController {

  3.     @RequestMapping(value = "/error", produces = Const.MIME.JSON)
  4.     public MatrixResponse error(HttpServletResponse resp, HttpServletRequest req) {
  5.         // 错误处理逻辑

  6.         return new MatrixResponse(ErrorCode.INTERNAL_ERROR);
  7.     }

  8.     @Override
  9.     public String getErrorPath() {
  10.         return "/error";
  11.     }
  12. }
复制代码
http://blog.csdn.net/neosmith/article/details/51090509

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-4-26 03:34 , Processed in 0.053883 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表