参考文档-springboot.doc
主要内容
- springboot默认的异常处理机制
- 使用自定义的页面来代替默认的异常页面
- 使用@controlleradvice+@handlerException来处理全局controller中的异常
- 使用实现ErrorController 来处理全局异常
springboot默认的异常处理机制
由官方文档所知,默认情况下,Spring Boot提供了一个/error以合理方式处理所有错误的映射(详情参考),对于计算机客户端,它会生成一个JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,有一个“whitelabel”错误视图,它以HTML格式呈现相同的数据
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
private final ErrorProperties errorProperties;
public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
this(errorAttributes, errorProperties, Collections.emptyList());
}
public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List errorViewResolvers) {
super(errorAttributes, errorViewResolvers);
Assert.notNull(errorProperties, "ErrorProperties must not be null");
this.errorProperties = errorProperties;
}
public String getErrorPath() {
return this.errorProperties.getPath();
}
//这是返回页面的
@RequestMapping(
produces = {"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = this.getStatus(request);
Map model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
return modelAndView == null ? new ModelAndView("error", model) : modelAndView;
}
//这是返回json格式的。
@RequestMapping
@ResponseBody
public ResponseEntity
在配置文件中,根据提示,可知映射路径确实是/error
测试:
@RequestMapping("exceptiontest")
@ResponseBody
public Object exceptionTest(){
throw new MyException(MyExceptionEnum.NOT_FOUND);
}
-
使用浏览器调用
-
使用postman调用
- 也可以直接调用/error接口,看看返回的是什么
使用自定义的页面来代替默认的异常页面
既然已经知道,springboot默认处理异常返回的是error页面,那么我们可以在templates目录下创建一个自定义的error页面
Title
this is my error page
测试:此时再用浏览器调用的话,就会出现自定义的error页面
使用实现ErrorController 来处理全局异常
我们可以模仿BasicErrorController来自定义一个ErrorController来处理全局的异常
@Controller
@RequestMapping("/error")
public class MyErrorController implements ErrorController {
private ErrorProperties errorProperties;
@Override
public String getErrorPath() {
return this.errorProperties.getPath();
}
@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HashMap map = new HashMap<>();
map.put("error","error_message");
ModelAndView modelAndView = new ModelAndView("error",map);
return modelAndView;
}
@RequestMapping
@ResponseBody
public ResponseEntity
error.html
Getting Started: Serving Web Content
结果:
那么为什么springboot会使用我们自定义的ErrorController而不使用自定义的了呢?可以在ErrorMvcAutoConfiguration类中发现,要是有了ErrorController,那么BasicErrorController就不会被注入到spring容器中
@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}
使用@controlleradvice+@handlerException来处理全局controller中的异常
1.定义一个自定义的异常枚举类
@Getter
@AllArgsConstructor
public enum MyExceptionEnum {
NOT_FOUND("404","不存在"),
NOT_ALLOWED("401","权限不够");
private String code;
private String message;
}
2.自定义异常类
@Data
@AllArgsConstructor
public class MyException extends RuntimeException {
private MyExceptionEnum myExceptionEnum;
}
3.定义一个异常处理类
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler()
@ResponseBody
public ResponseEntity handlerControllerException(Exception ex){
if(ex instanceof MyException){
MyExceptionEnum myExceptionEnum = ((MyException) ex).getMyExceptionEnum();
return new ResponseEntity(new ResponseMap(myExceptionEnum.getCode(),myExceptionEnum.getMessage()), HttpStatus.NOT_FOUND);
}
return null;
}
}
测试: