Spring Boot -- 异常处理
默认的异常处理
默认的异常处理有两种方式
- BasicErrorController 方式
- @ExceptionHandler 注解方式
在Spring boot开发中经常遇到“Whitelabel Error Page”白色标签错误页,这个页面当spring boot中发生错误时的默认处理方式,返回一个error页面,而这个页面的格式是固定的,这个页面有几个变量,映射地址:/error, status=404,type=Not Found。
SpringBoot的默认错误处理是BasicErrorController,支持两种格式:
- 错误页面 errorHtml
- json响应 error
Spring Boot默认的异常处理源码(BasicErrorController)
@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?modelAndView:new ModelAndView("error", model);
}
@RequestMapping
@ResponseBody
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = this.getStatus(request);
return new ResponseEntity(body, status);
}
errorHtml()返回错误页面
error()json响应错误
自定义的异常处理
BasicErrorController 方式
继承BasicErrorController ,并重写errorHtml()和error()
@Controller
public class DemoErrorController extends BasicErrorController {
public DemoErrorController(ServerProperties serverProperties){
super(new DefaultErrorAttributes(), serverProperties.getError());
}
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
response.setStatus(status.value());
System.out.println("do DemoErrorController errorHtml ......");
Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML));
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
}
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
//输出自定义的Json格式
Map<String, Object> map = new HashMap<>();
map.put("success", false);
map.put("msg", body.get("message"));
System.out.println("do DemoErrorController error ......");
return new ResponseEntity<>(map, status);
}
}
@ExceptionHandler 注解方式
通过AOP切面对controller进行异常植入
@ExceptionHandler的value定义的是要匹配的异常类型,这里写了一个总的异常Exception,可以针对某个具体的异常进行处理。
@ControllerAdvice
public class AllExceptionHandle {
@ExceptionHandler(value = Exception.class)
public ModelAndView errorHtmlHandle(HttpServletRequest request, Exception e) throws Exception{
System.out.println("do AllExceptionHandle errorHtmlHandle ......");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exception", e);
modelAndView.addObject("url", request.getRequestURL());
modelAndView.setViewName("error");
return modelAndView;
}
@ExceptionHandler(value = NullPointerException.class)
public Map<String, Object> errorJsonHandle(HttpServletRequest request, Exception e) throws Exception{
System.out.println("do AllExceptionHandle errorJsonHandle ......");
Map<String, Object> map = new HashMap<>();
map.put("exception", e);
map.put("url", request.getRequestURL());
return map;
}
}