SpringBoot错误处理

1 SpringMVC写法

1.1 在单独的Controller写一个处理异常的方法处理

@Slf4j
@RestController
public class HelloController { @GetMapping("/exception")
public String exception(){
int i = 1 / 0;
return "异常";
} /**
* 只能处理当前Controller发生的错误
*/
@ExceptionHandler
public String handlerException(Exception e){
return "exception...." + e.getMessage();
}
}

1.2 写一个异常处理类,使用@ControllerAdvice注解处理所有的Controller异常

public class GlobalExceptionHandler {

    @ResponseBody
@ExceptionHandler(Exception.class)
public String handlerException(Exception e){
return "发生错误,原因:" + e.getMessage();
}
}

2. SpringBoot处理流程分析

2.1 默认机制

错误处理的自动配置都在ErrorMvcAutoConfiguration中,两大核心机制:

  • SpringBoot 会自适应处理错误,响应页面或JSON数据
  • SpringMVC的错误处理机制依然保留,MVC处理不了,才会交给boot进行处理
  1. 解析一个错误页

    a. 如果发生了500、404、503、403 这些错误

    ⅰ. 如果有模板引擎,默认在 classpath:/templates/error/精确码.html

    ⅱ. 如果没有模板引擎,在静态资源文件夹下找 精确码.html

    b. 如果匹配不到精确码.html这些精确的错误页,就去找5xx.html,4xx.html模糊匹配

    ⅰ. 如果有模板引擎,默认在 classpath:/templates/error/5xx.html

    ⅱ. 如果没有模板引擎,在静态资源文件夹下找 5xx.html
  2. 如果模板引擎路径templates下有 error.html页面,就直接渲染

2.2 源码分析

发生错误以后,转发给/error路径,SpringBoot在底层写好一个 BasicErrorController的组件,专门处理这个请求。通过内容协商判断调用返回页面(errorHtml方法)还是json或xml格式(error方法)数据。

BasicErrorController.java

	@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections
.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
} @RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
return new ResponseEntity<>(body, status);
}

分析返回页面

//1、解析错误的自定义视图地址
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
//2、如果解析不到错误页面的地址,默认的错误页就是 error
return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);

解析自定义视图 AbstractErrorController.java

	protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status,
Map<String, Object> model) {
for (ErrorViewResolver resolver : this.errorViewResolvers) {
ModelAndView modelAndView = resolver.resolveErrorView(request, status, model);
if (modelAndView != null) {
return modelAndView;
}
}
return null;
}

通过容器的默认视图解析器解析错误页面DefaultErrorViewResolver.java

流程参考图示

	@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
ModelAndView modelAndView = resolve(String.valueOf(status.value()), 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) {
return new ModelAndView(errorViewName, model);
}
return resolveResource(errorViewName, model);
} private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
for (String location : this.resources.getStaticLocations()) {
try {
Resource resource = this.applicationContext.getResource(location);
resource = resource.createRelative(viewName + ".html");
if (resource.exists()) {
return new ModelAndView(new HtmlResourceView(resource), model);
}
}
catch (Exception ex) {
}
}
return null;
}

最佳实践

  • 前后分离

    后台发生的所有错误,@ControllerAdvice + @ExceptionHandler进行统一异常处理。
  • 服务端页面渲染
    • 不可预知的一些,HTTP码表示的服务器或客户端错误

      • 给classpath:/templates/error/下面,放常用精确的错误码页面。500.html,404.html
      • 给classpath:/templates/error/下面,放通用模糊匹配的错误码页面。 5xx.html,4xx.html
    • 发生业务错误
      • 核心业务,每一种错误,都应该代码控制,跳转到自己定制的错误页。
      • 通用业务,classpath:/templates/error.html页面,显示错误信息。

参考

https://www.yuque.com/leifengyang/springboot3/wp5l9qbu1k64frz1#CLn90

SpringBoot错误处理的更多相关文章

  1. SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念: SpringBoot 错误处理 2.具体内容 在之前的程序里面如果一旦出现了错误之后就会出现一堆的大白板,这个白板会 ...

  2. springboot错误: 找不到或无法加载主类

    一:当在eclipse启动spring boot项目时出现问题: springboot错误: 找不到或无法加载主类 解决办法: 1,通过cmd命令行,进入项目目录进行,mvn clean instal ...

  3. springboot 错误求解决

    最近再学习springboot这个好东西,结果给当成白老鼠了,我使用的是idea 2018  来测试  一个简单的界面跳转  ,结果报错了,在网上搜了好半天没搜到相应的解决方案,很头疼,希望哪位大神能 ...

  4. 学习小片段——springboot 错误处理

    一:先看看springboot默认的错误处理机制 springboot默认会判断是否是浏览器(http请求头Accept是否含有 text/html)来选择返回html错误页面或json错误信息 原因 ...

  5. springboot 错误处理

    在 java web开发过程中,难免会有一些系统异常或人为产生一些异常.在 RESTful springboot 项目中如何优雅的处理? 分析:在RESTful 风格的springboot 项目中,返 ...

  6. springboot错误页面处理

    springboot作为微服务的便捷框架,在错误页面处理上也有了一些新的处理,不同于之前的pringmvc500的页面处理是比较简单的,用java config或者xml的形式,定义如下的Bean即可 ...

  7. springboot 错误页面的配置

    springboot的错误页面,只需在templates下新建error文件夹,将404.500等错误页面放进去即可, springboot会自动去里面查找

  8. Springboot 错误处理机制

    SpringBoot默认的错误处理机制 即我们常见的白色的ErrorPage页面 浏览器发送的请求头: 如果是其他的请求方式,比如客户端,则相应一个json数据: 原理:是通过 ErrorMvcAut ...

  9. springboot错误1 Failed to execute goal org.springframework.boot:spring-boot-maven-plugin

    关于Springboot打包错误的问题 | Failed to execute goal org.springframework.boot:spring-boot-maven-plugin https ...

  10. SpringBoot错误经验

    1.在application.properties 添加 debug=true,可以看见项目的执行流程有助于调bug 2.如果错误显示端口号被占用 cmd 步骤1 查看端口号应用情况:netstat ...

随机推荐

  1. 「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!

    > 由于网页编辑器简陋,无法实现原文档的精心排版,如需原文档可联系... 序 「ximagine」在本篇文章中将介绍「荒岛」目前所使用的显示器测试流程及标准,我们主要使用Calman.Displ ...

  2. Docker 持续集成部署+ELK日志相关等 完美实践

    docker(ubuntu) 卸载docker # 卸载(如有) for pkg in docker.io docker-doc docker-compose docker-compose-v2 po ...

  3. 【收藏】default.rdp配置

    原文链接:  https://www.cnblogs.com/vman/archive/2011/12/05/2276895.html 存储在 Default.rdp 文件中的设置 默认情况下,将在& ...

  4. Flink学习(十九) 容错机制

    主要内容: 一致性检查点(checkpoint) 从检查点恢复到状态 Flink检查点算法 保存点(savepoint) 一致性检查点(checkpoint) Flink故障恢复机制的核心,就是应用状 ...

  5. 基于注意力机制与改进TF-IDF的推荐算法

    前言 本篇文章是2020年8月发表于<计算机工程>的一篇期刊论文,文章名称<基于注意力机制与改进TF-IDF的推荐算法>. 文章针对传统推荐系统主要依赖用户对物品的评分数据而无 ...

  6. 【由技及道】螺蛳壳里做道场-git仓库篇-gitlab-Vs-gitea【人工智障AI2077的开发日志001】

    指令接收:「开始构建代码宇宙」 系统检测:需求模糊度99.9% 启动应急协议:构建最小可行性生态圈 核心组件锁定:代码基因库(人类称之为Git仓库) 需求分析:论人类语言的艺术性 人类指令翻译机 表面 ...

  7. 【基础知识笔记】001 MATLAB-plotyy-函数详解

    plot 1 定义 plot()--matlab中二维画图的函数,函数返回值是各个线条的句柄. 2 调用格式 2.1 plot(y) 当y为向量时,是以y的分量为纵坐标,以元素序号为横坐标,用直线依次 ...

  8. Web前端入门第 13 问:HTML 标签和属性是否区分大小写?

    HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. 注意:以下截图都来源于 Chrome 浏览器,不同浏览器可能会产生不同的渲染结果. 思考一个问题:英文写法都分大 ...

  9. Qt解析JSON

    Qt解析JSON 文章目录 Qt解析JSON QT 解析json的三件套,QJsonDocument.QJsonObject.QJsonArray.QJsonValue JSON主要格式 QT的JSO ...

  10. HarmonyOS Next 鸿蒙开发-如何使用服务端下发的RSA公钥(字符串)对明文数据进行加密

    如何使用服务端下发的RSA公钥(字符串)对明文数据进行加密 将服务器下发的RSA公钥字符串替换掉pubKeyStr即可实现,具体可参考如下代码: import { buffer, util } fro ...