SpringBoot中的全局异常处理 (2)

定义方式如下:

/** * 自定义异常数据 * @author Summerday */ @Slf4j @Component public class MyErrorAttributes extends DefaultErrorAttributes { @Override public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) { Map<String, Object> map = super.getErrorAttributes(webRequest, options); if(map.get("status").equals(500)){ log.warn("服务器内部异常"); } return map; } } 四、自定义异常视图

自定义视图的加载逻辑存在于BasicErrorController类的errorHtml方法中,用于返回一个ModelAndView对象,这个方法中,首先通过getErrorAttributes获取到异常数据,然后调用resolveErrorView去创建一个ModelAndView对象,只有创建失败的时候,用户才会看到默认的错误提示页面。

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE) public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections .unmodifiableMap( //ErrorAttributes # getErrorAttributes getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); // E ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView != null) ? modelAndView : new ModelAndView("error", model); }

DefaultErrorViewResolver类的resolveErrorView方法:

@Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { // 以异常状态码作为视图名去locations路径中去查找页面 ModelAndView modelAndView = resolve(String.valueOf(status.value()), model); // 如果找不到,以4xx,5xx series去查找 if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = resolve(SERIES_VIEWS.get(status.series()), model); } return modelAndView; }

那么如何自定义呢?和自定义异常数据相同,如果我们定义了一个ErrorViewResolver的实例,默认的配置就会失效。

/** * 自定义异常视图解析 * @author Summerday */ @Component public class MyErrorViewResolver extends DefaultErrorViewResolver { public MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) { super(applicationContext, resourceProperties); } @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { return new ModelAndView("/hyh/resolve",model); } }

此时,SpringBoot将会去/hyh目录下寻找resolve.html页面。

五、@ControllerAdvice注解处理异常

前后端分离的年代,后端往往需要向前端返回统一格式的json信息,以下为封装的AjaxResult对象:

public class AjaxResult extends HashMap<String, Object> { //状态码 public static final String CODE_TAG = "code"; //返回内容 public static final String MSG_TAG = "msg"; //数据对象 public static final String DATA_TAG = "data"; private static final long serialVersionUID = 1L; public AjaxResult() { } public AjaxResult(int code, String msg) { super.put(CODE_TAG, code); super.put(MSG_TAG, msg); } public AjaxResult(int code, String msg, Object data) { super.put(CODE_TAG, code); super.put(MSG_TAG, msg); if (data != null) { super.put(DATA_TAG, data); } } public static AjaxResult ok() { return AjaxResult.ok("操作成功"); } public static AjaxResult ok(Object data) { return AjaxResult.ok("操作成功", data); } public static AjaxResult ok(String msg) { return AjaxResult.ok(msg, null); } public static AjaxResult ok(String msg, Object data) { return new AjaxResult(HttpStatus.OK.value(), msg, data); } public static AjaxResult error() { return AjaxResult.error("操作失败"); } public static AjaxResult error(String msg) { return AjaxResult.error(msg, null); } public static AjaxResult error(String msg, Object data) { return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data); } public static AjaxResult error(int code, String msg) { return new AjaxResult(code, msg, null); } }

根据业务的需求不同,我们往往也需要自定义异常类,便于维护:

/** * 自定义异常 * * @author Summerday */ public class CustomException extends RuntimeException { private static final long serialVersionUID = 1L; private Integer code; private final String message; public CustomException(String message) { this.message = message; } public CustomException(String message, Integer code) { this.message = message; this.code = code; } public CustomException(String message, Throwable e) { super(message, e); this.message = message; } @Override public String getMessage() { return message; } public Integer getCode() { return code; } }

@ControllerAdvice和@RestControllerAdvice这俩注解的功能之一,就是做到Controller层面的异常处理,而两者的区别,与@Controller和@RestController差不多。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjgyd.html