基于SpringBoot实现统一返回结果&统一异常处理

83 阅读1分钟

背景:最近在做一个新项目,整理框架的过程中想到基于SpringBoot来实现。但是发现了一个问题,网上其实有很多例子,但是有个问题,就是当调用的api抛异常的时候,也进了统一返回结果里,这块明显是不符合预期的。下面贴下代码,代码是我改造后的,下面这个是统一返回结果的类。

@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 判断类或者方法是否使用了 @ResponseResultBody
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return !returnType.getNestedParameterType().getSimpleName().equals(ResultData.class.getSimpleName());
    }

    //@SneakyThrows
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if(o instanceof String){
            try {
                return objectMapper.writeValueAsString(ResultData.success(o));
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return ResultData.success(o);
    }
}

大家看看上面代码中supports方法,里面我做了改造,网上很多例子就直接 return true.这样写是有问题的. 接下来,贴上统一返回结果的实体类

@Data
public class ResultData<T> {
    /** 结果状态 ,具体状态码参见ResultData.java*/
    private int status;
    private String message;
    private T data;
    private long timestamp ;

    public ResultData (){
        this.timestamp = System.currentTimeMillis();
    }

    public static <T> ResultData<T> success(T data) {
        ResultData<T> resultData = new ResultData<>();
        resultData.setStatus(ReturnCode.RC100.getCode());
        resultData.setMessage(ReturnCode.RC100.getMessage());
        resultData.setData(data);
        return resultData;
    }

    public static <t> ResultData<t> fail(int code, String message) {
        ResultData<t> resultData = new ResultData<>();
        resultData.setStatus(code);
        resultData.setMessage(message);
        return resultData;
    }
}

最后贴上全局异常处理的类 `

@Slf4j
@RestControllerAdvice
public class RestExceptionHandler {
    /**
     * 默认全局异常处理。
     * @param e the e
     * @return ResultData
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResultData<String> exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return ResultData.fail(ReturnCode.RC500.getCode(),e.getMessage());
    }

    @ExceptionHandler(ReteLimitingException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
    public ResultData<String> rateLimitingException(Exception e) {
        log.error("限流 ex={}", e.getMessage(), e);
        return ResultData.fail(ReturnCode.RC429.getCode(),e.getMessage());
    }

}

`