当前位置:   article > 正文

springboot全局统一返回处理_springboot统一返回封装

springboot统一返回封装


前言

项目中一般都会有规定好的接口返回格式,无论成功与失败,一般格式都是不变的,这样是为了方便前后端统一处理,今天就来说下前后端统一处理的较为优雅的方式;


一、统一的返回格式

一般而言都会有一个统一的返回类作为接口的返回数据的封装,例如:

@Data
public class Result<T> implements Serializable {

    private int code = HttpStatus.OK.value();

    private String msg;

    private T data;


    public static <T> Result<T> success() {
        return success(null);
    }


    public static <T> Result<T> failure() {
        return failure(HttpStatus.BAD_REQUEST.value(),HttpStatus.BAD_REQUEST.getReasonPhrase());
    }

    public static <T> Result<T> success(T data) {
        return new Result<T>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
    }

    public static <T> Result<T> failure(int errorCode, String errorMsg) {
        return failure(errorCode, errorMsg, null);
    }

    public static <T> Result<T> failure(int code, String errorMsg, T data) {
        return new Result<T>(code, errorMsg, data);
    }

    public Result(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

然后我们通过此类作为返回参数的统一封装,这样无论成功与否,都是三个参数
code msg data

二、全局异常处理

  • 项目中难免会有异常抛出
    1. 服务端报错的异常
    2. 处理逻辑中的异常(参数校验, 逻辑不通等)
  • 由于我们一般都是前后端分离项目,所以都是接口方式的返回,那么我们只需要处理接口就可以了
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel {

    @ExceptionHandler(ValidationException.class)
    public Result<String> handleException(ValidationException e) {
        e.printStackTrace();
        log.error("参数校验发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public Result<String> exceptionHandler(NullPointerException e) {
        e.printStackTrace();
        log.error("空指针异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(value = {Exception.class, RuntimeException.class})
    public Result<String> exceptionHandler(Exception e) {
        e.printStackTrace();
        log.error("运行时发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    public Result<String> handException(AsyncRequestTimeoutException e) {
        e.printStackTrace();
        log.error("运行时超时异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

一般来说控制器可以这样用

@RestController
@RequestMapping("lang")
public class LangController {
    @RequestMapping("get")
    public Result get(){
        return Result.success(LocalUtil.get("demo"));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三、全局返回处理(装逼用的)

还是上面的全局异常处理,不过要增加点东西

  • 实现ResponseBodyAdvice接口
  • 实现两个方法
    完整代码如下:
@RestControllerAdvice
@Slf4j
public class ControllerExceptionHandel implements ResponseBodyAdvice<Object>{

    @Autowired
    private ObjectMapper objectMapper;

    @ExceptionHandler(ValidationException.class)
    public Result<String> handleException(ValidationException e) {
        e.printStackTrace();
        log.error("参数校验发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public Result<String> exceptionHandler(NullPointerException e) {
        e.printStackTrace();
        log.error("空指针异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(value = {Exception.class, RuntimeException.class})
    public Result<String> exceptionHandler(Exception e) {
        e.printStackTrace();
        log.error("运行时发生异常:{}", e.getMessage());
        return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    public Result<String> handException(AsyncRequestTimeoutException e) {
        e.printStackTrace();
        log.error("运行时超时异常:{}", e.getMessage());
        return Result.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

        Class<?> returnClass = returnType.getMethod().getReturnType();
        if (body instanceof String || Objects.equals(returnClass, String.class)) {
            return objectMapper.writeValueAsString(Result.success(body));
        }
        if (body instanceof Result) {
            return body;
        }
        return Result.success(body);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

这样控制器中既可以像之前那样使用,还可以像如下使用
它会自动封装返回结果,无需手动封装

@RestController
@RequestMapping("lang")
public class LangController {

    @RequestMapping("get")
    public String get(){
        return LocalUtil.get("demo");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

总结

如果项目中按照这种方式 @RestControllerAdvice + ResponseBodyAdvice接口,就能实现大部分的统一返回出参功能了,无论是正常请求还是异常请求,无论是简单类型还是集合返回,相当于都有了统一的封装处理;
快试试,用到项目中吧~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/184008?site
推荐阅读
相关标签
  

闽ICP备14008679号