目录
一、springboot的错误处理机制
处理错误机制的管理类
给容器中添加了三个组件DefaultErrorAttributes、BasicerrorController、ErrorPageCustomizer、DefaultErrorResolver
错误处理步骤
一旦系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定义错误的响应规则),一旦出现错误请求,就会首先被BasicErrorController所处理
ErrorPageCustomizer
这里可以设置错误页面位置
BasicErrorController的处理
映射规则:server.error.path-->error.path-->/error
浏览器处理错误
传入配置信息,通过ModelAndView进行页面的跳转
跳转错误页面通过resolveErrorView方法
对错误页面进行解析
综述所述,我们自定义错误页面,只需要将它放到静态文件夹下面即可
运行
客户端处理错误
传入配置信息,返回json的错误数据
为什么能够自动区分客户端和浏览器错误请求呢?
在浏览器请求头部,会发送一个text/html
在客户端请求中我们可以看到它是“*/*”
总结:在浏览器发送的请求来到errorHtml方法,在客户端发送的请求来到error方法
DefaultErrorAttributes
共享错误信息错误信息
页面能够获取的
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误信息
直接从页面获取错误消息数据
运行效果
自定义浏览器错误界面及底层源码分析
如果模板引擎没有错误界面,将它移动到static静态资源文件夹下
在静态资源的情况下,无法使用el表达式
如果静态以及模板引擎都没有写错误界面,将会来到springboot默认的错误页面中
如果在解析错误页面的时候,没有找到就会返回null
返回null它就会自己new一个对象
返回的就是一个springboot自定义的错误界面
自定义客户端错误页面及底层源码分析
抛出一个自定义异常
运行,还是会跳转到默认的错误页面
创建5xx的错误页面
再次运行
用客户端访问返回的就是json数据
创建一个异常处理器
运行,这样返回的json数据就是我们自定义的方式
访问页面返回的也是我们自定义的json数据
但是问题来了,我们这样的话,拦截异常处理以后不管是客户端还是浏览器返回的都是json数据
因此,我们通过直接重定向的方式,将错误信息交给/error来进行自适应响应处理
但是现在可以实现自适应,但是页面跳转还是空白界面而不是我们自定义的错误页面
而且我们发现在我们拦截错误请求之后默认的都是200的状态码错误
底层源码
在我们没有传入状态码的时候就会默认200
设置状态码
运行
但是问题又来了,我们传过去的错误信息它还是使用的是异常类中的,我们处理这里的错误信息并没有传递过去
运行之后
现在我们进行分析:出现错误以后,会来到/error请求,会被BasicErrorController处理
我们可以看到不管是浏览器还是客户端处理的错误信息都是通过getErrorAttributes(在AbstractErrorController中)来获取的
所以我们也可以通过继承Abstract,ErrorController抽象类,来重写它对于浏览器和客户端的处理,可以实现错误信息的显示
返回的是errorattributes.geterrorattributes()
因此我们也可以自己写一个该方法
首先将请求数据map放入到request域中
给容器中加入我们自定义的ErrorAttributes
运行
最终效果:响应式自适应的,可以通过定制ErrorAttributes改变需要返回的内容