Spring Boot(五)——错误处理机制

一、SpringBoot默认的错误处理机制

1.1原理

       可以参照ErrorMvcAutoConfiguration错误处理的自动配置,给容器中添加了一下组件:

@Bean
    @ConditionalOnMissingBean(
        value = {ErrorAttributes.class},
        search = SearchStrategy.CURRENT
    )
// 帮我们在页面定制错误信息
    public DefaultErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());
    }

    @Bean
    @ConditionalOnMissingBean(
        value = {ErrorController.class},
        search = SearchStrategy.CURRENT
    )
//处理 /error请求
// 产生HTML类型数据,产生json数据
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes, ObjectProvider<ErrorViewResolver> errorViewResolvers) {
        return new BasicErrorController(errorAttributes, this.serverProperties.getError(), (List)errorViewResolvers.orderedStream().collect(Collectors.toList()));
    }
 @Bean
//系统出现错误以后来到error请求进行处理
    public ErrorMvcAutoConfiguration.ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) {
        return new ErrorMvcAutoConfiguration.ErrorPageCustomizer(this.serverProperties, dispatcherServletPath);
    }
@Bean
        @ConditionalOnBean({DispatcherServlet.class})
        @ConditionalOnMissingBean({ErrorViewResolver.class})
        DefaultErrorViewResolver conventionErrorViewResolver() {
            return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties);
        }

1.2步骤

一旦系统出现4××或5××之类的错误,ErrorPageCustomizer就会生效(定制错误的响应规则),就会来到/error请求,就会被BasicErrorController处理

1)响应页面,去哪个页面是由 DefaultErrorViewResolver 得到的 

二、定制错误响应

2.1定制HTML数据

     2.1.1有模板引擎的情况下

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

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

        

页面能获取到的信息:

           timestamp   :  时间戳

           status   :  状态码

           error    : 错误提示

           exception  :   异常对象

           message   : 异常消息

           errors   : JSR303数据校验的错误在这里

如:

<h1>status:[[${status}]]</h1>
<h2>timestamp:[[${timestamp}]]</h2>

     2.1.2没有模板引擎

模板引擎找不到这个错误页面,静态资源文件夹下找,只不过不会动态显示信息。

     2.1.3以上都没有错误页面,就是默认来到springboot默认的错误提示页面。

2.2定制JSON数据

2.2.1浏览器服务器返回的都是json

2.2.2自适应

转发到  /error进行自适应响应效果处理

@ExceptionHandler(UserNotExistException.class)
    public String handlerException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user.no.exist");
        map.put("message",e.getMessage());
        //传入自己的错误状态码  否则就不会进入定制错误页面的解析流程
        request.setAttribute("javax.servlet.error.status_code","400");
        //转发到   /error
        return "forward:/error";
    }

2.2.3定制数据携带出去

出现错误以后,会来到/error请求,会被 BasicErrorController处理,响应出去可以获取的数据是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);

1)、可以完全来编写一个ErrorController的实现类【或者编写AbstractErrorController】,放在容器中。  --麻烦

2)、页面上能用的数据,或者json返回能调用的数据都是通过errorAttributes.getErrorAttributes得到。   --使用

//给容器加入我们自定义的ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        map.put("comapny","tchuhu");
        //我们异常处理器携带的数据
        Map<String, Object> ext =(Map<String, Object>) webRequest.getAttribute("ext", 0);
        map.put("ext",ext);
        return super.getErrorAttributes(webRequest, includeStackTrace);
    }
}

效果:

<h1>status:[[${status}]]</h1>
<h2>timestamp:[[${timestamp}]]</h2>
<h2>exception:[[${exception}]]</h2>
<h2>message:[[${message}]]</h2>
<h2>ext:[[${ext.code}]]</h2>
<h2>ext:[[${ext.message}]]</h2>
发布了25 篇原创文章 · 获赞 5 · 访问量 4499

猜你喜欢

转载自blog.csdn.net/qq_41605068/article/details/104127250