错误处理机制
springboot的默认错误处理机制
在浏览器上默认返回的是一个错误页面,下面所示

因为在浏览器中请求优先接收text/html数据

在其他的客户端默认返回的是json字符串
因为在其他的客户端的接收参数是: accept:"*/*"
springboot错误处理机制原理
具体的我们可以参考源码ErrorMvcAutoConfiguration,
在这个自动配置类里面主要给给容器添加了下面重要的组件:
DefaultErrorAttributes
BasicErrorController
ErrorPageCustomizer
DefaultErrorViewResolver
BasicErrorController
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
@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 ? new ModelAndView("error", model) : modelAndView);
}
@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<Map<String, Object>>(body, status);
}
点进resolveErrorView进行查看,可以看出这个方法是得到所有的ErrorViewResolver
进行解析,如果解析成功就返回回去,否则就返回null
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;
}
ErrorPageCustomizer
里面就是在系统出现错误之后来到error请求
里面的getPath()就是从配置文件里面获取配置的值
如果取不出,默认是/error
@Value("${error.path:/error}")
private String path = "/error";
private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
private final ServerProperties properties;
protected ErrorPageCustomizer(ServerProperties properties) {
this.properties = properties;
}
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(this.properties.getServletPrefix()
+ this.properties.getError().getPath());
errorPageRegistry.addErrorPages(errorPage);
}