我是靠谱客的博主 仁爱台灯,这篇文章主要介绍SpringBoot web--错误处理(学习笔记19),现在分享给大家,希望可以做个参考。

1、比如说:

我先注释掉拦截器,让问题重现一下:



这里我访问一个不存在的请求路径,就出现了错误(There was an unexpected error (type=Not Found, status=404).)。通过客户端 Postman 模拟请求一下(下图所示),默认响应一个  JSON 数据:


原理:

    可以参照 ErrorMvcAutoConfiguration 进行错误处理的自动配置。

    给容器中添加了以下组件:

    1、DefaultErrorAttributes

复制代码
1
2
3
4
5
        @Bean @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException()); }

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

复制代码
1
2
3
4
5
        @Bean @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers); }

    下面两个方法:第一个是产生 html 类型的数据(浏览器请求),第二个是产生 JSON 数据(客户端请求)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        @RequestMapping(produces = "text/html") public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes( request, isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); ModelAndView modelAndView = resolveErrorView(request, response, status, model);// 去哪个页面作为错误页面 return (modelAndView != null ? modelAndView : new ModelAndView("error", model)); } @RequestMapping @ResponseBody public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = getStatus(request); return new ResponseEntity<>(body, status); }

    区分是浏览器请求还是客户端请求:

    浏览器:

    

    客户端:    

    


3、ErrorPageCustomizer

复制代码
1
2
3
4
        @Bean public ErrorPageCustomizer errorPageCustomizer() { return new ErrorPageCustomizer(this.serverProperties); }

    4、DefaultErrorViewResolver

复制代码
1
2
3
4
5
6
        @Bean @ConditionalOnBean(DispatcherServlet.class) @ConditionalOnMissingBean public DefaultErrorViewResolver conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, his.resourceProperties); }

    规则说明:

        如果系统出现 4xx 或者 5xx 之类的错误,ErrorPageCustomizer 就会生效(定制错误的响应规则)

复制代码
1
2
3
4
5
6
7
        @Override public void registerErrorPages(ErrorPageRegistry errorPageRegistry) { ErrorPage errorPage = new ErrorPage( this.properties.getServlet().getServletPrefix() this.properties.getError().getPath()); errorPageRegistry.addErrorPages(errorPage); }

        通过 this.properties.getError().getPath(), 得到 path 信息:

复制代码
1
2
3
4
5
        /** * Path of the error controller. */ @Value("${error.path:/error}") private String path = "/error";

     就会来到/error请求; 就会被 BasicErrorController 处理(参考 BasicErrorController 下的两段代码),去哪个页面显示。去哪个页面是由 DefaultErrorViewResolver 解析的:

复制代码
1
2
3
4
5
6
7
8
public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered { private static final Map<Series, String> SERIES_VIEWS; static { Map<Series, String> views = new EnumMap<>(Series.class); views.put(Series.CLIENT_ERROR, "4xx"); views.put(Series.SERVER_ERROR, "5xx"); SERIES_VIEWS = Collections.unmodifiableMap(views); }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { ModelAndView modelAndView = resolve(String.valueOf(status), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = resolve(SERIES_VIEWS.get(status.series()), model); } return modelAndView; } private ModelAndView resolve(String viewName, Map<String, Object> model) { String errorViewName = "error/" + viewName; TemplateAvailabilityProvider provider = this.templateAvailabilityProviders .getProvider(errorViewName, this.applicationContext);// 模板引擎可以解析这个页面地址就用模板引擎解析 if (provider != null) {//模板引擎可用的情况下返回到errorViewName指定的视图地址 return new ModelAndView(errorViewName, model); } return resolveResource(errorViewName, model);//模板引擎不可用,就在静态资源文件夹找errorViewName对应的页面 error/404.html,如果没有返回为null }

2、如何定制错误响应

    2.1:如果是浏览器访问不存在请求路径,跳转错误页面,错误页面是定制的,要和整体网站的风格一致。

        2.1.1、有模板引擎的情况下:根据 error/状态码,将错误页面命名为:错误状态.html(404.html、4xx.html);把它们放在模板引擎文件夹里面的 error 文件夹下,发生相应的状态的错误就会找到对应的页面。

                    我们可以使用 4xx.html 和 5xx.html 页面来匹配相应状态码所有的错误(如果状态码没有匹配到具体的错误页面,就会指向此状态码统一页面。精确优先)

        2.1.2、没有模板引擎:模板引擎找不到错误页面,静态资源文件夹下存在

        2.1.3、模板引擎下没有、静态资源下也没有:就会使用默认的页面

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
        @Configuration @ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true) @Conditional(ErrorTemplateMissingCondition.class) protected static class WhitelabelErrorViewConfiguration { private final SpelView defaultErrorView = new SpelView( "<html><body><h1>Whitelabel Error Page</h1>" + "<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>" + "<div id='created'>${timestamp}</div>" + "<div>There was an unexpected error (type=${error}, status=${status}).</div>" + "<div>${message}</div></body></html>"); @Bean(name = "error") @ConditionalOnMissingBean(name = "error") public View defaultErrorView() { return this.defaultErrorView; } // If the user adds @EnableWebMvc then the bean name view resolver from // WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment. @Bean @ConditionalOnMissingBean public BeanNameViewResolver beanNameViewResolver() { BeanNameViewResolver resolver = new BeanNameViewResolver(); resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10); return resolver; } }

    2.2:如果是客户端请求,则要统一数据,定制返回数据

   

3、定制错误页面、返回定制错误json数据,并把定制数据进行显示

1、完全可以编写一个ErrorController的实现类 或者 编写AbstractErrorController的子类,放在容器中

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

感谢--尚硅谷


最后

以上就是仁爱台灯最近收集整理的关于SpringBoot web--错误处理(学习笔记19)的全部内容,更多相关SpringBoot web--错误处理(学习笔记19)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(92)

评论列表共有 0 条评论

立即
投稿
返回
顶部