(26)实验 - 错误处理原理,定制错误数据

1 SpringBoot默认的错误处理机制

默认效果:

(1) 浏览器,返回一个默认的错误页面
(2) 如果是其他客户端,默认响应一个json数据

有时候在写CRUD的时候,比如说访问一个不存在的地址。
(1)浏览器,返回一个默认的错误页面
报错
(26)实验 - 错误处理原理,定制错误数据
(2)如果是其他客户端,默认响应一个json数据
(26)实验 - 错误处理原理,定制错误数据

原理可以参照: ErrorMvcAutoConfiguration
(26)实验 - 错误处理原理,定制错误数据

2 如何定制错误响应

我们每次访问错误页面的时候会报错,(26)实验 - 错误处理原理,定制错误数据

但是我们不想弹出这样子的页面,那么如何编写呢?

查看 错误配置文件 ErrorMvcAutoConfiguration
包含的组件有

1)DefaultErrorAttributes:

(26)实验 - 错误处理原理,定制错误数据

2)BasicErrorController::处理默认/error请求

(26)实验 - 错误处理原理,定制错误数据

3)ErrorPageCustomizer:

(26)实验 - 错误处理原理,定制错误数据

4)DefaultErrorAttributes:

(26)实验 - 错误处理原理,定制错误数据
步骤:
一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error 请求;就会被BasicErrorController处理;

1)响应页面;去哪个页面是由DefaultErrorViewResolver解析得到的;

3 如果定制错误响应:

3.1 如何定制错误的页面

1)、有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的 error文件夹下】,发生此状态码的错误就会来到 对应的页面;

此时用的模板引起是thymeleaf:默认文件夹是templates

我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态 码.html);

(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
页面能获取的信息;
timestamp:时间戳

status:状态码
error:错误提示

exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里

2)、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;
3)、以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

3.2 如何定制错误的json数据

新建类:
(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据

但是我们想要出现我们默认定制的500页面。
在模板引擎下放一个5xx.html页面

(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
再次刷新,来到了我们自己定制的页面,然后就可以访问到5xx.html页面了。
(26)实验 - 错误处理原理,定制错误数据

JSON中出现的错误页面怎么处理呢?
(26)实验 - 错误处理原理,定制错误数据
我们怎么响应我们自己写的JSON定制规则的错误处理显示呢?

我们自己来写一个异常处理器
在SpringMVC中 要成为异常处理器 必须要标注@ControllerAdvice

处理异常,什么异常?
使用注解@ExceptionHandler(xxxx.class)

(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据
访问页面模式:

(26)实验 - 错误处理原理,定制错误数据

可以使用SpringMVC的ExceptionHandler机制捕获到异常 ,然后用JSON数据输出出来。

弊端: 但是这么一写的话,浏览器和客户端Postman都会显示报错JSON数据

如何变成自适应的请求?
当浏览器请求错误的时候弹出浏览器的错误,
当客户端请求错误的时候弹出JSON的数据。

查看源码。

(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据
我们的浏览器效果:
(26)实验 - 错误处理原理,定制错误数据
客户端:
(26)实验 - 错误处理原理,定制错误数据

自适应的效果是达到了,可是浏览器放回的页面有问题。
(26)实验 - 错误处理原理,定制错误数据
查看源码:
(26)实验 - 错误处理原理,定制错误数据
然后编写代码:

(26)实验 - 错误处理原理,定制错误数据
再次访问相同的页面:
(26)实验 - 错误处理原理,定制错误数据
改成500
(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据

3.3 将我们的定制数据携带出去

出现错误以后,会来到/error请求,会被BasicErrorController处理,响应出去可以获取的数据是由 getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);
1、完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中;

2、页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到;
容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;
自定义ErrorAttributes

(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
(26)实验 - 错误处理原理,定制错误数据
客户端:
终的效果:响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容,
(26)实验 - 错误处理原理,定制错误数据

(26)实验 - 错误处理原理,定制错误数据