如果没有进行特别配置,Spring Boot在页面出错时,默认效果基本是以下情况:
(1)浏览器返回一个默认的错误页面如图1-6所示。
图1-6
浏览器发送请求的请求头如图1-7所示。
图1-7
(2)如果是其他客户端,默认响应一个JSON数据,如图1-8和图1-9所示。
图1-8
图1-9
出现上述错误页面的原困是:Spring Boot中的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请求
通过类上的@RequestMapping注解可以知道,Spring Boot默认的错误处理映射路径/error是从errorHtml方法上面的注解@RequestMapping(produces = "text/html")可以知道这个方法是返回错误页面的,从error方法上面的注解@ResponseBody可以知道这个方法是返回错误JSON数据的。
在处理错误请求时,调用父类的getErrorAttributes方法来获取错误信息,调用父类的resolveErrorView解析错误视图。
(3)ErrorPageCustomizer
@Value("${error.path:/error}") private String path = "/error";
系统出现错误以后,转到error请求进行处理,该路径可以自定义。
(4)DefaultErrorViewResolver
系统页面出现错误时,ErrorPageCustomizer就会生效(定制错误的响应规则),然后会转到/error请求,被BasicErrorController处理。出错后的响应页面,是由DefaultErrorViewResolver解析得到的、进入ErrorViewResolver的resolveErrorView方法提供的。ErrorViewResolver主要用于解析错误视图,通过这个类,可以通过错误请求的HttpStatus错误代码将template文件夹下的error/HttpStatus.html文件解析成我们想要的视图。如果template下没有对应的文件,Spring Boot还会到静态资源文件夹下查找对应的HTML文件。
(1)有模板引擎的情况下,将错误页面命名为“错误状态码.html”放在模板引擎文件夹里面的error文件夹下,发生此状态码的错误就会转到对应的页面,我们可以使用4xx和5xx作为错误页面的文件名,来匹配这种类型的所有错误,匹配时精确优先(优先寻找精确的状态码.html文件)。
页面能获取的信息:
· timestamp:时间戳。
· status:状态码。
· error:错误提示。
· exception:异常对象。
· message:异常消息。
· errors:JSR303数据校验的错误都在这里。
(2)没有模板引擎(模板引擎找不到这个错误页面),就到静态资源文件夹下查找。
(3)以上都没有错误页面,就是默认转到Spring Boot默认的错误提示页面。
(1)自定义异常处理与返回定制的JSON数据
(2)转发到/error进行自适应响应效果处理
出现错误以后,/error请求会被BasicErrorController处理,响应页面中可以获取的数据是由getErrorAttributes得到的。getErrorAttributes是AbstractErrorController(ErrorController)规定的方法。
编写一个ErrorController的实现类,或者编写AbstractErrorController的子类,放在容器中。
页面上能用的数据,或者是JSON返回能用的数据,都通过errorAttributes.getErrorAttributes()得到。
容器中有个DefaultErrorAttributes.getErrorAttributes(),设计该方法的目的主要是为了进行数据处理,开发中我们结合具体情况可以对该方法进行重写。
自定义ErrorAttributes代码如下:
响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容。