Spring Boot Web应用的异常处理
2016-04-07 23:19
651 查看
Web应用在处理请求时可能会出现多种错误,如请求参数不正确、URL不存在、请求方法错误、内部未知错误等。SpringMVC有多种异常处理方式,使用某种方式的判断标准是,你的异常是在请求处理的哪个阶段发生的。
先说说RESTful应用,由于返回的是JSON而不是页面,因此在异常处理方法中就不能返回
有人可能会问,
对于非RESTful应用,则需要返回一个View。这时使用
从SpringMVC源码中可知,
在执行@RequestMapping方法时发生的异常
这也是最常见的异常了,处理业务逻辑时可能会发生各种问题,如数据库报错、请求参数格式错误/缺失/值非法等。此类异常的捕获方法有两种,对于提供RESTful服务的应用,使用
@ControllerAdvice和
@ExceptionHandler注解; 对于使用模板渲染HTML的应用,实现
HandlerExceptionResolver接口。
先说说RESTful应用,由于返回的是JSON而不是页面,因此在异常处理方法中就不能返回
ModelAndView对象(如果非要如此,也可以返回只包含一个JSON字符串的
View)。一个典型的RESTful异常处理类如下:
/** * 异常处理器。该类会处理所有在执行标有@RequestMapping注解的方法时发生的异常 * Created by whf on 4/7/16. */ @ControllerAdvice public class RestExceptionHandler extends ResponseEntityExceptionHandler { /** * 处理@RequestParam错误, 即参数不足 * @return */ @Override protected ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return new ResponseEntity<>(new MatrixResponse(ErrorCode.ARG_INVALID), status); } /** * 处理500错误 * @return */ @Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { //log.error("got internal error : {}", ex); // 请求方式不支持 if (ex instanceof HttpRequestMethodNotSupportedException) { return new ResponseEntity<>(new MatrixResponse(ErrorCode.REQUEST_METHOD_UNSUPPORTED), status); } return new ResponseEntity<>(new MatrixResponse(ErrorCode.INTERNAL_ERROR), status); } /** * 处理参数类型转换失败 * @param request * @return */ @Override protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { //log.error("type mismatch"); return new ResponseEntity<>(new MatrixResponse(ErrorCode.ARG_INVALID), status); } }
有人可能会问,
@ExceptionHandler注解去哪了?要注意的是,SpringMVC为我们提供了一个通用的异常处理逻辑,即
ResponseEntityExceptionHandler类,该类的
handleException()方法上标注了
@ExceptionHandler注解。此方法会判断 Exception 的类型,对于每一种类型,会交由对应的
protected handleXXXX()方法处理,子类只需要重写对应的方法即可。
对于非RESTful应用,则需要返回一个View。这时使用
HandlerExceptionResolver:
@Component public class ExceptionHandler implements HandlerExceptionResolver { private static Logger log = LoggerFactory.getLogger(ExceptionHandler.class); @Autowired private Mail mail; @Override public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object handler, Exception ex) { // 异常处理逻辑 goes here log.info("got exception: {}", ex.getClass()); return new ModelAndView("pc/500"); } }
从SpringMVC源码中可知,
DispatcherServlet中如果产生了异常,则接下来会在
processDispatchResult()方法中查询当前容器中是否有
HandlerExceptionResolver接口的实现类,如果有则调用它的
resolveException()方法,得到返回的
View,如果没有则使用框架默认的异常处理类。
在执行@RequestMapping之前遇到的异常
该类异常通常是因为SpringMVC没有找到能处理当前请求的控制器造成的,比如最常见的404。此时@ControllerAdvice就不起作用了,因为
@RequestMapping方法根本没找到,更不可能执行。此时我们要写一个
@RestController,并实现
ErrorController接口:
@RestController public class FinalExceptionHandler implements ErrorController { @RequestMapping(value = "/error", produces = Const.MIME.JSON) public MatrixResponse error(HttpServletResponse resp, HttpServletRequest req) { // 错误处理逻辑 return new MatrixResponse(ErrorCode.INTERNAL_ERROR); } @Override public String getErrorPath() { return "/error"; } }
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring Boot 开发微服务
- 如何优雅地处理前端异常?
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- C#异常处理详解
- 轻松学习C#的异常处理
- PHP异常处理Exception类
- 使用jQuery.wechat构建微信WEB应用
- JS异常处理的一个想法(sofish)
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- springmvc 发送ajax出现中文乱码的解决方法汇总
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- struts2 spring整合fieldError问题
- PHP 的异常处理、错误的抛出及回调函数等面向对象的错误处理方法