Spring Boot学习笔记(十九)使用@RestControllerAdvice 统一返回信息格式,统一处理错误返回给前端的信息

参考Spring Boot @RestControllerAdvice 统一异常处理、@RestControllerAdvice构造统一返回值格式和统一异常处理、SpringBoot 使用 beforeBodyWrite 实现统一的接口返回类型

1.创建好我们的统一返回格式

//这些是lombok的注解
@Data
@NoArgsConstructor 
@AllArgsConstructor
public class CommonResponse<T> {
     
    private boolean success;
    private int code;
    private String message;
    private T data;

    public CommonResponse(Integer code, String message, Boolean success) {
     
        this.code = code;
        this.message = message;
        this.success = success;
    }
}

2. 实现RestControllerAdvice,完成对返回信息的捕获

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice {
     

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
     
        //通过方法参数得到类名, 然后得到类上的annotation,
        // 如果被IgnoreResponseAdvice标识就不拦截
        if (methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
     
            return false;
        }

        //方法上被标注,也不拦截
        if (methodParameter.getMethod().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )){
     
            return false;
        }
        return true;
    }

    // beforeBodyWrite 即在写入相应之前
    // 所以在这里构造统一格式
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
     
        CommonResponse<Object> response = new CommonResponse<>(0,"", true);
        if (null == o) {
     
// 若是null 则不进行处理
        } else if (o instanceof CommonResponse) {
     
        	// 若返回类型是commonResponse,则不进行修改,
        	// 这是为了防止对原本的代码产生影响
        	//(原本的代码中,有些返回的类型可能就是CommonResponse)
            response = (CommonResponse<Object>) o;
        } else {
     
            response.setData(o);
        }
        return response;
    }
}

3. 测试

@Controller
public class UserController {
     
    @PostMapping("/justTest")
    @ResponseBody
    public User justTest(@RequestBody User user) {
     
        return user;
    }
}

Spring Boot学习笔记(十九)使用@RestControllerAdvice 统一返回信息格式,统一处理错误返回给前端的信息_第1张图片
返回结果正如我们的预期,但是如果是错误呢?
我们将代码修改为如下所示,以进行测试

    @PostMapping("/justTest")
    @ResponseBody
    public User justTest(@RequestBody User user) {
     
        int i = 1/0;
        return user;
    }

再次使用postman进行测试
Spring Boot学习笔记(十九)使用@RestControllerAdvice 统一返回信息格式,统一处理错误返回给前端的信息_第2张图片
发现data中是错误信息,但是我们的success字段仍然为true,这不是我们所想要的。

4. 对错误进行统一处理,

在CommonResponseDataAdvice添加@ExceptionHandler方法

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice {
     
    // 之前的代码省略不显示

    // 错误捕捉,一个Controller下多个ExceptionHandler的异常类型不能一样
    @ExceptionHandler(value = Exception.class)
    public CommonResponse<String> handlerGlobeException(HttpServletRequest request, Exception exception){
     
        CommonResponse<String> response=new CommonResponse<>(0,"发生错误", false);
        response.setData(exception.getMessage());
        return  response;
    }
}

再次在进行测试,发现结果如下所示,成功捕捉了错误
Spring Boot学习笔记(十九)使用@RestControllerAdvice 统一返回信息格式,统一处理错误返回给前端的信息_第3张图片

5. 自定义错误处理

我们新建一个自定义一个错误类,一般来说继承Exception或者是其子类 RuntimeException。
可以这样理解这有两个类,
Exception 是某些可以恢复的错误,这些是用户设置什么的犯下的错误。
RunTimeException 是不可以恢复的错误,无能为力,这些是程序员犯下的错误。

5.1我们自定义一个错误类

public class CommonException extends Exception {
     
    public CommonException(String message) {
     
        super(message);
    }
}

5.2 修改CommonResponseDataAdvice的代码

在代码中,添加新的错误处理,处理CommonException的错误

    @ExceptionHandler(value = CommonException.class)
    public CommonResponse<String> handlerCommonException(HttpServletRequest request, Exception exception){
     
        CommonResponse<String> response=new CommonResponse<>(0,"这边是commonException的错误处理", false);
        response.setData(exception.getMessage());
        return  response;
    }

5.3 修改我们的Controller代码,进行测试

@Controller
public class UserController {
    @PostMapping("/justTest")
    @ResponseBody
    public User justTest(@RequestBody User user) {
        //假设这里对username进行验证(比如查重),发现用户名与数据库的重复了
        if (user.getUserName().equals("重复的用户名")) {
            throw new CommonException("用户名重复,这样不行");
        } else {
            // 如果userName没有重复再进行其他业务操作
        }
        return user;
    }
}

Spring Boot学习笔记(十九)使用@RestControllerAdvice 统一返回信息格式,统一处理错误返回给前端的信息_第4张图片
可发现成功触发了我们写在 CommonResponseDataAdvice 中的 commonException 的错误处理

你可能感兴趣的:(#,Spring,Boot,Advice,RestController,统一处理,统一格式,spring,boot)