SpringBoot处理全局统一异常

迈不过友情╰ 2021-09-19 23:24 530阅读 0赞

在后端发生异常或者是请求出错时,前端通常显示如下

复制代码

  1. Whitelabel Error Page
  2. This application has no explicit mapping for /error, so you are seeing this as a fallback.
  3. Fri Jun 07 15:38:07 CST 2019
  4. There was an unexpected error (type=Not Found, status=404).
  5. No message available

复制代码

对于用户来说非常不友好。

本文主要讲解如何在SpringBoot应用中使用统一异常处理。

实现方式

第一种:使用@ControllerAdvice和@ExceptionHandler注解

第二种: 使用ErrorController类来实现。

第一种:使用@ControllerAdvice和@ExceptionHandler注解

复制代码

  1. @Slf4j
  2. @ControllerAdvice
  3. public class GlobalExceptionHandler {
  4. @ResponseBody
  5. @ExceptionHandler(NullPointerException.class)
  6. public BaseResult globalException(HttpServletResponse response,NullPointerException ex){
  7. log.info("GlobalExceptionHandler...");
  8. log.info("错误代码:" + response.getStatus());
  9. BaseResult result = new WebResult(WebResult.RESULT_FAIL,"request error:"+response.getStatus()
  10. ,"GlobalExceptionHandler:"+ex.getMessage());
  11. return result;
  12. }
  13. }

复制代码

注解@ControllerAdvice表示这是一个控制器增强类,当控制器发生异常且符合类中定义的拦截异常类,将会被拦截。

可以定义拦截的控制器所在的包路径

复制代码

  1. @Target({ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Component
  5. public @interface ControllerAdvice {
  6. @AliasFor("basePackages")
  7. String[] value() default {};
  8. @AliasFor("value")
  9. String[] basePackages() default {};
  10. Class<?>[] basePackageClasses() default {};
  11. Class<?>[] assignableTypes() default {};
  12. Class<? extends Annotation>[] annotations() default {};
  13. }

复制代码

注解ExceptionHandler定义拦截的异常类

  1. @Target({ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface ExceptionHandler {
  5. Class<? extends Throwable>[] value() default {};
  6. }

第二种: 使用ErrorController类来实现。

系统默认的错误处理类为BasicErrorController,将会显示如上的错误页面。

这里编写一个自己的错误处理类,上面默认的处理类将不会起作用。

getErrorPath()返回的路径服务器将会重定向到该路径对应的处理类,本例中为error方法。

复制代码

  1. @Slf4j
  2. @RestController
  3. public class HttpErrorController implements ErrorController {
  4. private final static String ERROR_PATH = "/error";
  5. @ResponseBody
  6. @RequestMapping(path = ERROR_PATH )
  7. public BaseResult error(HttpServletRequest request, HttpServletResponse response){
  8. log.info("访问/error" + " 错误代码:" + response.getStatus());
  9. BaseResult result = new WebResult(WebResult.RESULT_FAIL,"HttpErrorController error:"+response.getStatus());
  10. return result;
  11. }
  12. @Override
  13. public String getErrorPath() {
  14. return ERROR_PATH;
  15. }
  16. }

复制代码

测试

以上定义了一个统一的返回类BaseResult,方便前端进行处理。

复制代码

  1. package com.microblog.common.result;
  2. import java.io.Serializable;
  3. public class BaseResult implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. public static final int RESULT_FAIL = 0;
  6. public static final int RESULT_SUCCESS = 1;
  7. //返回代码
  8. private Integer code;
  9. //返回消息
  10. private String message;
  11. //返回对象
  12. private Object data;
  13. public BaseResult(Integer code, String message) {
  14. this.code = code;
  15. this.message = message;
  16. }
  17. public BaseResult(Integer code, String message, Object object) {
  18. this.code = code;
  19. this.message = message;
  20. this.data = object;
  21. }
  22. public Integer getCode() {
  23. return code;
  24. }
  25. public void setCode(Integer code) {
  26. this.code = code;
  27. }
  28. public String getMessage() {
  29. return message;
  30. }
  31. public void setMessage(String message) {
  32. this.message = message;
  33. }
  34. public Object getData() {
  35. return data;
  36. }
  37. public void setData(Object data) {
  38. this.data = data;
  39. }
  40. }

复制代码

编写一个测试控制器

复制代码

  1. @Slf4j
  2. @RestController
  3. @RequestMapping("/user")
  4. public class TestController {
  5. @RequestMapping("/info1")
  6. public String test(){
  7. log.info("/user/info1");
  8. throw new NullPointerException("TestController have exception");
  9. }
  10. }

复制代码

1.发出一个错误的请求,也就是没有对应的处理类。

从返回可以看到是由HttpErrorController类处理

  1. {"code":0,"message":"HttpErrorController error:404","data":null}

2.发出一个正常的请求(TestController的test()处理),处理类中抛出空异样

从返回中可以看出是由GlobalExceptionHandler类处理

  1. {"code":0,"message":"request error:200","data":"GlobalExceptionHandler:TestController have exception"}

区别

1.注解@ControllerAdvice方式只能处理控制器抛出的异常。此时请求已经进入控制器中。

2.类ErrorController方式可以处理所有的异常,包括未进入控制器的错误,比如404,401等错误

3.如果应用中两者共同存在,则@ControllerAdvice方式处理控制器抛出的异常,类ErrorController方式未进入控制器的异常。

4.@ControllerAdvice方式可以定义多个拦截方法,拦截不同的异常类,并且可以获取抛出的异常信息,自由度更大。

如果你对编程感兴趣或者想往编程方向发展,可以关注微信公众号【筑梦编程】,大家一起交流讨论!小编也会每天定时更新既有趣又有用的编程知识!

发表评论

表情:
评论列表 (有 0 条评论,530人围观)

还没有评论,来说两句吧...

相关阅读

    相关 springboot异常全局统一处理

    [个人博客][Link 1] 日常后端业务开发中,在提供接口服务时会遇到各种异常处理,通常涉及到参数校验异常、自定义异常以及一些不可预知的异常等等。下面就来说一下在sprin