1.在Spring boot 中如果发生错误,浏览器访问会默认跳转到Whitelabel Error Page 这个错误页面,如果是客户端访问的话返回JSON格式的错误数据,说明spring boot 为全局的异常处理做了自适应处理,浏览器和客户端分别响应不同的形式的错误数据。

{
"timestamp": 1534818780468,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/amain.html"
}

2.spring boot 对错误信息的处理都在它的自动的配置里实现,对于异常的自动配置都在org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration 中实现。首先,我们来看浏览器端如何响应错误。这个自动配置类为容器中添加一下几个组件:

(1)当系统发生错误以后,ErrorPageCustomizer 会响应错误,就会发送/error请求去处理错误。

@Bean
public ErrorPageCustomizer errorPageCustomizer() {
  return new ErrorPageCustomizer(this.serverProperties);
}

(2)由BasicErrorController 去处理error请求,在BasicErrorController 中根据请求报文头的produces = "text/html" 判断是浏览器还是客户端请求, 用方法errorHtml 响应浏览器请求的错误页面,  error响应客户端请求而的错误页面 。

@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}

(3)接下来由 DefaultErrorViewResolver 去解析错误页面的视图,最终解析出来的视图的名称是: error/ +status,如果模板引擎可用的话就在模板文件夹下的error文件夹下找以错误状态码命名的错误页面,如果不可用则在静态资源文件夹下的error文件夹下找以错误状态码命名的错误文件。如果没有错误状态码命名的出错误文件,还可以按照以4开头的错误去找4xx命名的错误页面,5开头的错误去找5xx命名的错误页面,如果以上都没有的话就会来到默认的Whitelabel Error Page 这个错误页面

@Bean
@ConditionalOnBean(DispatcherServlet.class)
@ConditionalOnMissingBean
public DefaultErrorViewResolver conventionErrorViewResolver() {
return new DefaultErrorViewResolver(this.applicationContext,
this.resourceProperties);
}

(4)DefaultErrorAttributes这个组件里面放置了错误信息,封装了

timestamp:时间戳

​ status:状态码

​ error:错误提示

​ exception:异常对象

​ message:异常消息

​ errors:JSR303数据校验的错误

这些错误信息

@Bean
@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
public DefaultErrorAttributes errorAttributes() {
return new DefaultErrorAttributes();
}

(5)综上所述,对于浏览器端的错误响应页面,我们只需要在模板文件夹夹下简历error文件夹,在这里放置以错误状态码命名的错误页面,或者放置以4xx,5xx命名的错误页面,来响应所有以4或者5开头的错误页面。

2.如何定制客户端返回的json形式的错误信息

定制json格式的错误信息的原理就是,在我们拦截到错误错误信息后,设置错误信息后将错误转发给/error请求,这样BasicErrorController 就会去处理这个请求,进行自适应处理。在进行BasicErrorController 中进行自适应处理的时候,是根据请求的状态码来映射错误页面的,而这个错误的状态码是从request中获取的,这样只要我们在异常处理的过程中设置状态码,他就会去找相应的错误页面,从而达到自适应的效果。

Integer statusCode = (Integer) request
.getAttribute("javax.servlet.error.status_code");

那么我就可以来定制自己的错误处理类

@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)
public String handlerException(Exception e,HttpServletRequest request) {
request.setAttribute("javax.servlet.error.status_code",500);
return "forward:/error";
}
}

但是,这里返回的信息只是错误本身的一些信息,如果我们需要自己定义一些额外的信息,比如异常的说明或者提示,那该怎么办呢?我们上面介绍了DefaultErrorAttributes 这个足迹是用来封装错误信息的,而且这个组件添加了@ConditionalOnMissingBean注解,只有在容器中没有这个组件的时候它才能生效,这样我们就可以定做自己的ErrorAttributes ,将我们需要的额外信息添加进去,然后将我们自己定制的组件添加进容器即可。如果希望浏览器也返回json格式的错误信息的话,可以添加@ResponseBody注解,将错误信息封装好,返回即可。

@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)
public String handlerException(Exception e,HttpServletRequest request) {
request.setAttribute("javax.servlet.error.status_code",500);
Map<String, Object> map = new HashMap<>();
      //捕获异常后添加自己的错误信息
map.put("code", "0000");
map.put("msg", "出错了,请稍后再试!");
request.setAttribute("errorMsg", map);
      //转发给BaseErrorController
return "forward:/error";
}
}
@Component
public class MyErrorattributes extends DefaultErrorAttributes{
  //重写
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
// TODO Auto-generated method stub
Map<String,Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
     //获取并将自定义的错误信息添加到ErrorAttributes
Map<String, Object> errorMsg = (Map<String, Object>) requestAttributes.getAttribute("errorMsg", 0);
map.put("errorMsg", errorMsg);
return map;
}
}

浏览器效果:

客户端效果:

spring boot-11.全局捕获异常的更多相关文章

  1. Spring Boot 中全局异常处理器

    Spring Boot 中全局异常处理器,就是把错误异常统一处理的方法.等价于Springmvc中的异常处理器. 步骤一:基于前面的springBoot入门小demo修改 步骤二:修改HelloCon ...

  2. Spring Boot → 11:项目实战-账单管理系统完整版

    Spring Boot → 11:项目实战-账单管理系统完整版

  3. spring boot 2 全局统一返回RESTful风格数据、统一异常处理

    全局统一返回RESTful风格数据,主要是实现ResponseBodyAdvice接口的方法,对返回值在输出之前进行修改.使用注解@RestControllerAdvice拦截异常并统一处理. 开发环 ...

  4. Spring Boot集成全局唯一ID生成器

    流水号生成器(全局唯一 ID生成器)是服务化系统的基础设施,其在保障系统的正确运行和高可用方面发挥着重要作用.而关于流水号生成算法首屈一指的当属 Snowflake雪花算法,然而 Snowflake本 ...

  5. Spring Boot入门——全局异常处理

    1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dependency> <groupId>org.springfr ...

  6. Spring Boot (11) mybatis 关联映射

    一对多 查询category中的某一条数据,同时查询该分类下的所有Product. Category.java public class Category { private Integer id; ...

  7. spring boot(11)-druid监控

    druid druid是和tomcat jdbc一样优秀的连接池,出自阿里巴巴.关于druid连接池参数,参考 https://github.com/alibaba/druid/wiki/DruidD ...

  8. Spring boot 梳理 - 全局配置文件application.properties或者是application.yml,在resources目录下或者类路径下的/config下,一般我们放到resources下。

    全局配置文件application.properties或者是application.yml,在resources目录下或者类路径下的/config下,一般我们放到resources下.

  9. Spring Boot配置全局异常捕获

    1 SpringBoot配置全局的异常捕获 项目的说明 配置thymeleaf作为视图模板 ExceptionController.java模拟测试用 MyAjaxExceptionHandler.j ...

  10. Spring Boot—11控制器Controller

    package com.sample.smartmap.controller; import org.springframework.beans.factory.annotation.Autowire ...

随机推荐

  1. Java多线程和并发(五),线程的状态

    目录 1.线程的六个状态 2.sleep和wait的区别 3.锁池(EntryList)和等待池(WaitSet) 4.notify和notifyall的区别 五.线程的状态 1.线程的六个状态 2. ...

  2. AtCoder AGC036C GP 2 (组合计数)

    题目链接 https://atcoder.jp/contests/agc036/tasks/agc036_c 题解 终于有时间补agc036的题了. 这题其实不难的来着--我太菜了考场上没想出来 首先 ...

  3. C++入门经典-例6.4-输出字符数组中的内容

    1:代码如下: // 6.4.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using ...

  4. C++入门经典-例2.3-在print函数中使用附加符号

    1:代码如下: // 2.3.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" int main() { ; /*定义长整型变量,为其赋值*/ ...

  5. C++入门经典-例2.2-使用格式输出函数printf

    1:使用printf函数对不同类型变量进行输出,%符号,代表输出类型,\n代表换行,代码如下: // 2.2.cpp : 定义控制台应用程序的入口点. // #include "stdafx ...

  6. Mysql 中需不需要commit

    摘自:https://blog.csdn.net/zzyly1/article/details/81003122 mysql在进行增删改操作的时候需不需要commit,这得看你的存储引擎, 如果是不支 ...

  7. ASP.NET中的物理路径与虚拟路径

    物理路径:c:\PathsAndURLs\Content\Colors.html虚拟路径:(http://localhost:53274/Content/Colors.html)路径中端口号后面的那部 ...

  8. 数据框架对比:Hadoop、Storm、Samza、Spark和Flink——flink支持SQL,待看

    简介 大数据是收集.整理.处理大容量数据集,并从中获得见解所需的非传统战略和技术的总称.虽然处理数据所需的计算能力或存储容量早已超过一台计算机的上限,但这种计算类型的普遍性.规模,以及价值在最近几年才 ...

  9. 手机APP测试——Perfecto

    基于 Perfecto mobile cloud 的移动端自动化测试实践 本文将介绍 Pefecto mobile cloud 在移动端自动化测试的应用. Pefecto 将真实移动设备放到 clou ...

  10. Cas服务器以及客户端搭建

    一.搭建cas服务器 官网:http://jasig.github.io/cas/ Cas Server 下载:http://developer.jasig.org/cas/ Cas Client 下 ...