通常我们在SpringBoot中设置的统一异常处理只能处理Controller抛出的异常。有些请求在到达Controller之前就已经发生了异常,而这些异常无法被统一的异常捕获,比如Servlet容器的一些异常。今天在项目开发中遇到一个,让我很苦恼,因为它返回的错误信息的格式无法统一处理,于是决定想办法解决这个问题。ErrorPageFilterWhitelabelErrorPage这样的图相信大家也很常见吧。只要SpringBoot出错,页面上反映的就是这个。如果您使用Postman之类的工具来测试异常:{"timestamp":"2021-04-29T22:45:33.231+0000","status":500,"message":"InternalServerError","path":"foo/bar"}这是如何实现的?SpringBoot在启动时会注册一个ErrorPageFilter。当Servlet发生异常时,过滤器会根据不同的策略拦截并处理异常:当异常已经被处理时,则直接处理,否则转发到相应的错误页面。有兴趣的可以看看源码,逻辑并不复杂,这里就不贴了。另外,当一个Servlet抛出异常时,处理异常的Servlet可以从HttpServletRequest中得到几个属性,如下:异常属性我们可以从上面的属性中得到异常的详细信息。默认的错误页面通常在SpringBoot中出现异常时默认跳转到/error进行处理,/error的相关逻辑由BasicErrorController实现。@Controller@RequestMapping("${server.error.path:${error.path:/error}}")publicclassBasicErrorControllerextendsAbstractErrorController{//返回错误页面@RequestMapping(produces=MediaType.TEXT_HTML_VALUE)publicModelAndViewerrorHtml(HttpServletRequestrequest,HttpServletResponseresponse){atusH=getStatus(request);Mapmodel=Collections.unmodifiableMap(getErrorAttributes(request,getErrorAttributeOptions(request,MediaType.TEXT_HTML)));response.setStatus(status.value());ModelAndViewmodelAndView=resolveErrorView(请求,response,status,model);return(modelAndView!=null)?modelAndView:newModelAndView("error",model);}//返回json@RequestMappingpublicResponseEntity