springboot 异常处理
Author:SimpleWu
默认错误处理机制
SpringBoot 默认的错误处理直接回返回对应的错误视图页面. 比如 404 错误.
如果是其它客户端访问, 默认相应一个 JSON 数据. 比如通过 postman 来访问当前页面.
springboot 错误页面处理过程:
SpringBoot 的错误信息配置是通过 ErrorMvcAutoConfiguration 来进行配置的, 这个类中帮我们注册了一下组件.
DefaultErrorAttributes: 帮我们在页面上共享错误信息.
BasicErrorController: 处理默认的 / error 请求. 分为两种处理请求的方式, 一种是 html 方式, 一种是 JSON 方式.
ErrorPageCustomizer: 系统发生错误后, 该对象就会生效, 来定义请求规则.
DefaultErrorViewResolver: 默认的错误视图解析器, 将错误信息解析到相应的错误视图.
处理 error 请求过程: 一旦系统出现 4xx 或者 5xx 之类的错误, ErrorPageCustomizer 就会生效 (定义错误的相应规则), 就会来到 / error 请求. 就会被 BasicErrorController 处理. BasicErrorController 会根据请求头 RequestHeaders 中的 Accept 来区分是浏览器发送的请求还是其它工具发出的请求. 分为两个处理方法, 一个是 errorHtml() 和 error(), 在 errorHtml()方法中, 获取错误状态信息, 由 resolveErrorView 解析器解析到默认的错误视图页面. 错误页面是 / error/404.HTML 页面. 如果 templates 中 error 里面有这个页面 404 错误就会精确匹配 404.HTML 如果没有这个 404.HTML 他会模糊匹配 4xx.HTML 页面, 如果 templates 中没有找到错误页面, 它就会去 static 文件中找.
页面可以获取的错误信息:
timestamp: 时间戳.
status: 状态码.
error: 错误提示.
exception: 异常对象.
message: 异常消息.
errors: 数据效验相关的信息.
注意: static 文件夹存放的是静态页面, 它没有办法使用模板引擎表达式
了解了上面的计息过程以后, 我们自定义错误就简单了. 自定义 HTML 错误页面分为两种情况:
有模板引擎的情况下, 在 templates 文件夹下建立一个 error 文件夹, 里面以错误号的方式添加错误页面. 我们也可以使用 4xx 和 5xx 作为错误页面的文件名来匹配这种类型的其它错误, 精确优先.
没有模板引擎的情况下, 在静态资源文件夹下添加以错误号命名的错误页面.
自定义异常返回 JSON 数据
这种异常处理方式没有自适应效果, 不论页面还是其它工具都会返回 JSON 格式的数据.
- @ControllerAdvice
- public class MyExceptionHandler {
- @ResponseBody
- @ExceptionHandler(RuntimeException.class)
- public Map<String,Object> handleException(Exception e){
- Map<String,Object> map = new HashMap<>();
- map.put("code","user.notexist");
- map.put("message",e.getMessage());
- return map;
- }
- }
这种处理方式错误码是 500 他首先会去模板引擎 error 中找定制的错误页面, 没有就会去静态资源文件中 error 文件夹去.
- @ControllerAdvice
- public class MyExceptionHandler {
- @ExceptionHandler(UserNotExistException.class)
- public String handleException(Exception e, HttpServletRequest request){
- Map<String,Object> map = new HashMap<>();
- // 传入我们自己的错误状态码 4xx 5xx, 否则就不会进入定制错误页面的解析流程
- //Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
- request.setAttribute("javax.servlet.error.status_code",500);
- map.put("code","user.notexist");
- map.put("message",e.getMessage());
- // 转发到 / error
- return "forward:/error";
- }
- }
来源: https://www.cnblogs.com/SimpleWu/p/10044468.html