错误处理机制:
访问一个不存在的页面时,或者程序抛出异常时
默认效果
- 浏览器返回一个错误的页面,注意查看浏览器发送请求的请求头
- 可以使用专业的软件比如postman分析返回的json数据
springboot错误处理的自动配置信息
主要给日容器中注册了以下组件:
- ErrorPageCustomizer 系统出现错误以后来到error请求进行处理;相当于(web.xml注册的错误页面规则)
- BasicErrorController 处理/error请求
- DefaultErrorViewResolver 默认的错误视图解析器
- DefaultErrorAttributes 错误信息
- defaultErrorView 默认错误视图
@getErrorAttributes()返回的参数
- timestamp:时间戳
- status:状态码
- error:错误提示
- exception:异常对象
- message:异常消息
- errors:JSR303数据校验的错误都在这里
2.0以后默认是不显示exception的,需要在配置文件中开启
server.error.include-exception=true
如何定制JSON数据
springboot做了自适应效果,浏览器访问响应错误页面。客户端访问响应错误信息的json数据
-
第一种方法,定义全局异常处理器类注入到容器中,捕获到异常返回json格式的数据
@ControllerAdvice public class MyExceptionHandler {@ResponseBody@ExceptionHandler(Exception.class)public Map<String, Object> handleException(Exception e) {Map<String, Object> map = new HashMap(2);map.put("code", "100011");map.put("msg", e.getMessage());return map;} }
- 由上面我们已经知道数据的来源是调用DefaultErrorAttributes的getErrorAttributes方法得到的,而这个DefaultErrorAttributes是在ErrorMvcAutoConfiguration配置类中注册的,并且注册之前会检查容器中是否已经拥有
@Bean@ConditionalOnMissingBean(value = {ErrorAttributes.class},search = SearchStrategy.CURRENT)public DefaultErrorAttributes errorAttributes() {return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());}
所以我们可以只要实现ErrorAttributes接口或者继承DefaultErrorAttrites类,然后注册到容器中就行了
@ControllerAdvice
public class MyExceptionHandler {@ExceptionHandler(Exception.class)public String handleException(Exception e, HttpServletRequest request) {Map<String, Object> map = new HashMap(2);map.put("name", "hello");map.put("password", "123456");//设置状态码request.setAttribute("javax.servlet.error.status_code", 500);//把数据放到request域中request.setAttribute("ext", map);return "forward:/error";}
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Beanpublic DefaultErrorAttributes errorAttributes() {return new MyErrorAttributes();}class MyErrorAttributes extends DefaultErrorAttributes {@Overridepublic Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {//调用父类的方法获取默认的数据Map<String, Object> map = new HashMap<>(super.getErrorAttributes(webRequest, includeStackTrace));//从request域从获取到自定义数据Map<String, Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", RequestAttributes.SCOPE_REQUEST);map.putAll(ext);return map;}}......