SpringBoot默认的错误处理机制

即我们常见的白色的ErrorPage页面

浏览器发送的请求头:

如果是其他的请求方式,比如客户端,则相应一个json数据:

原理;是通过 ErrorMvcAutoConfiguration,错误处理的自动配置;

给容器中添加了以下组件

1、DefaultErrorAttributes:

帮我们在页面共享信息;
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>();
errorAttributes.put("timestamp", new Date());
addStatus(errorAttributes, requestAttributes);
addErrorDetails(errorAttributes, requestAttributes, includeStackTrace);
addPath(errorAttributes, requestAttributes);
return errorAttributes;
}

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

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController { @RequestMapping(produces = "text/html")//产生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 ? new ModelAndView("error", model) : modelAndView);
} @RequestMapping
@ResponseBody //产生json数据,其他客户端来到这个方法处理;
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<Map<String, Object>>(body, status);
}

3、ErrorPageCustomizer:

@Value("${error.path:/error}")
private String path = "/error"; 系统出现错误以后来到error请求进行处理;(web.xml注册的错误页面规则)

4、DefaultErrorViewResolver:

@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) {
//默认SpringBoot可以去找到一个页面? error/404
String errorViewName = "error/" + viewName; //模板引擎可以解析这个页面地址就用模板引擎解析
TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
.getProvider(errorViewName, this.applicationContext);
if (provider != null) {
//模板引擎可用的情况下返回到errorViewName指定的视图地址
return new ModelAndView(errorViewName, model);
}
//模板引擎不可用,就在静态资源文件夹下找errorViewName对应的页面 error/404.html
return resolveResource(errorViewName, model);
}

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

1)响应页面;去哪个页面是由DefaultErrorViewResolver解析得到的;

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

2)、如何定制错误响应:

  如何定制错误的页面

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

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

​ 页面能获取的信息;

​ timestamp:时间戳

​ status:状态码

​ error:错误提示

​ exception:异常对象

​ message:异常消息

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

​ 2)、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;

​ 3)、以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

如何定制错误的json数据;

Controller.MyExceptionHandler

package com.project.javasystem.Controller;

import com.project.javasystem.exception.UserNotExistException;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map; @ControllerAdvice
public class MyExceptionHandler { //方法一:
//浏览器,客户端都返回的是Json数据
/* @ResponseBody//响应json数据
@ExceptionHandler(UserNotExistException.class)
public Map<String,Object> handleException(Exception e){
Map<String,Object>map = new HashMap<>();
map.put("code:","User.notExit");
map.put("message:",e.getMessage());
return map;
}*/ //方法二:自适应效果
@ExceptionHandler(UserNotExistException.class)
public String handleException(Exception e,HttpServletRequest request){
Map<String,Object>map = new HashMap<>();
//传入自定义的状态码
/*Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");*/
request.setAttribute("javax.servlet.error.status_code",500);
map.put("code:","User.NotExit");
map.put("message:","用户出错啦");
//转发到error进行自适应处理
request.setAttribute("MyError",map);
//转发到error
return "forward:/error";
}
}

3)、将我们的定制数据携带出去;

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

​ 1、完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中;

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

​ 容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;

自定义ErrorAttributes

Component.MyErrorAttributes

package com.project.javasystem.Component;

import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
import java.util.Map; @Component
public class MyErrorAttributes extends DefaultErrorAttributes { //返回值 map中就是页面和json能获取的所有字段
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest,includeStackTrace);
map.put("CompanyName","517NA");
// 异常处理器携带的数据
Map<String,Object>MyError = (Map<String, Object>) webRequest.getAttribute("MyError", 0);
map.put("MyError",MyError);
return map;
}
}

最终的效果:响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容,

Springboot 错误处理机制的更多相关文章

  1. SpringBoot(六) -- SpringBoot错误处理机制

    一.SpringBoot中的默认的错误处理机制 1.在SpringBootWeb开发中,当我们访问请求出现错误时,会返回一个默认的错误页面: 2.在使用其他客户端访问的时候,则返回一个json数据: ...

  2. Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析

    前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...

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

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

  4. 4_6.springboot2.xWeb开发之错误处理机制

    1.SpringBoot默认的错误处理机制 默认效果:1).浏览器,返回一个默认的错误页面 浏览器发送请求的请求头: ​ 2).如果是其他客户端,默认响应一个json数据 原理: ​ 默认情况下,Sp ...

  5. linux系统编程之错误处理机制

    在讲解liunx错误处理机制之前我们先来看一段代码: #include<sys/types.h> #include<sys/stat.h> #include<fcntl. ...

  6. javascript中的错误处理机制

    × 目录 [1]对象 [2]类型 [3]事件[4]throw[5]try[6]常见错误 前面的话 错误处理对于web应用程序开发至关重要,不能提前预测到可能发生的错误,不能提前采取恢复策略,可能导致较 ...

  7. Map/Reduce 工作机制分析 --- 错误处理机制

    前言 对于Hadoop集群来说,节点损坏是非常常见的现象. 而Hadoop一个很大的特点就是某个节点的损坏,不会影响到整个分布式任务的运行. 下面就来分析Hadoop平台是如何做到的. 硬件故障 硬件 ...

  8. Android IOS WebRTC 音视频开发总结(七五)-- WebRTC视频通信中的错误恢复机制

    本文主要介绍WebRTC视频通信中的错误恢复机制(我们翻译和整理的,译者:jiangpeng),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blac ...

  9. PHP异常与错误处理机制

    先区别一下php中错误 与 异常的概念吧 PHP错误:是属于php程序自身的问题,一般是由非法的语法,环境问题导致的,使得编译器无法通过检查,甚至无法运行的情况.平时遇到的warming.notice ...

随机推荐

  1. Intellij 生成exe可执行文件

    生成jar包 编写源代码 此处我使用kotlin来编码,主函数实际功能就是输出一行文字. /** * 应用入口 * @author mazaiting */ object TestExe { ​ @J ...

  2. fsockopen用feof读取http响应内容的一些问题

    在前面三个例子中,都有这么一段代码: while (!feof($fp)) { // 读取文件/数据 //$content .= fgets($fp, 128); //$line = fread($f ...

  3. 是时候考虑让你的Spark跑在K8S上了

    [摘要] Spark社区在2.3版本开始,已经可以很好的支持跑着Kubernetes上了.这样对于统一资源池,提高整体资源利用率,降低运维成本(特别是技术栈归一)有着非常大的帮助.这些趋势是一个大数据 ...

  4. 链接脚本(Linker Script)用法解析(一) 关键字SECTIONS与MEMORY

    1.MEMORY关键字用于描述一个MCU ROM和RAM的内存地址分布(Memory Map),MEMORY中所做的内存描述主要用于SECTIONS中LMA和VMA的定义. 2.SECTIONS关键字 ...

  5. 智能家居CC2530功率放大组网RFX2401C和AT2401C的区别

    两者最大的区别就是RFX2401C的增益为12dbmAT2401C的增益为14dbm这就会导致AT2401C的功耗会比RFX2401C大一点点,但距离也会相对更远,并且增加了EDS防静电等级,多出2个 ...

  6. openstack网络(一)

    什么是OpenStack Networking OpenStack网络的特性 交换机 路由器 负载均衡 防火墙 虚拟专用网络 网络功能虚拟化 网络类型 管理网络 API 网络 外部网络 访客网络 在一 ...

  7. C#语言和SQL Server数据库技术_My Bank银行系统

    第一个类: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System ...

  8. CoderForces-617B

    Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is g ...

  9. (全国多校重现赛一)F-Senior Pan

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...

  10. Dubbo源码分析之 SPI(一)

    一.概述 dubbo SPI 在dubbo的作用是基础性的,要想分析研究dubbo的实现原理.dubbo源码,都绕不过 dubbo SPI,掌握dubbo SPI 是征服dubbo的必经之路. 本篇文 ...