美文网首页
springcloud框架下如何优雅的进行统一返回值和异常封装

springcloud框架下如何优雅的进行统一返回值和异常封装

作者: Xiaojun | 来源:发表于2021-03-28 00:14 被阅读0次

FeignErrorDecoder:对feign调用异常进行封装

@Slf4j
@Configuration
public class FeignErrorDecoder extends ErrorDecoder.Default {

    @Override
    public Exception decode(String methodKey, Response response) {
        Exception exception = super.decode(methodKey, response);

        if (exception instanceof RetryableException) {
            return exception;
        }

        try {
            if (exception instanceof FeignException && ((FeignException) exception).responseBody().isPresent()) {
                ByteBuffer responseBody = ((FeignException) exception).responseBody().get();
                String bodyText = StandardCharsets.UTF_8.newDecoder().decode(responseBody.asReadOnlyBuffer()).toString();
                ExceptionInfo exceptionInfo = JSON.parseObject(bodyText, ExceptionInfo.class);
                Integer code = Optional.ofNullable(exceptionInfo.getCode()).orElse(ResultCodeEnum.ERROR.getCode());
                String message = Optional.ofNullable(exceptionInfo.getMessage()).orElse(ResultCodeEnum.ERROR.getMessage());
                return new BusinessException(code, message);
            }
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return exception;
    }
}

@RestControllerAdvice和@ExceptionHandler对web模块进行异常封装

@Slf4j
@RestControllerAdvice
public class WebGlobalExceptionHandler {

    @ExceptionHandler({FeignException.class})
    @ResponseBody
    public R<?> feignExceptionHandler(FeignException exception) {
        log.error(exception.getMessage(), exception);
        return R.error(exception.getMessage());
    }

    @ExceptionHandler({RuntimeException.class})
    @ResponseBody
    public R<?> runtimeExceptionHandler(RuntimeException exception) {
        log.error(exception.getMessage(), exception);
        return R.error(exception.getMessage());
    }

    @ExceptionHandler({Exception.class})
    @ResponseBody
    public R<?> exceptionHandler(Exception exception) {
        log.error(exception.getMessage(), exception);
        return R.error(exception.getMessage());
    }

    @ExceptionHandler({BusinessException.class})
    public R<?> businessExceptionHandler(BusinessException exception) {
        log.error(exception.getMessage(), exception);
        return R.error(exception.getCode(), exception.getMessage());
    }

    @ExceptionHandler({BindException.class})
    @ResponseBody
    public R<?> bindExceptionHandler(BindException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.get(0).getDefaultMessage();
        log.error(errorMessage, exception);
        return R.error(ResultCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public R<?> validateExceptionHandler(MethodArgumentNotValidException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        String errorMessage = fieldErrors.get(0).getDefaultMessage();
        log.error(errorMessage, exception);
        return R.error(ResultCodeEnum.ERROR_PARAMETER.getCode(), errorMessage);
    }
}

@ControllerAdvice 统一封装web的返回值

@ControllerAdvice(basePackages = "tech.xproject.web.manager")
public class ResponseHandler implements ResponseBodyAdvice<Object> {

    /**
     * 是否支持advice功能
     * treu=支持,false=不支持
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     *
     * 处理response的具体业务方法
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if(o.getClass().equals(R.class)){
                //这里如果web有异常会优先被统一异常处理先捕获,所以如果判断为R类型,直接返回
                return oR;
        }
        return R.success(o);
    }
}

晚点贴上完整demo

参考文章:
Feign自定义ErrorDecoder错误时返回统一结构
https://blog.csdn.net/new9xgh/article/details/107934862

相关文章

网友评论

      本文标题:springcloud框架下如何优雅的进行统一返回值和异常封装

      本文链接:https://www.haomeiwen.com/subject/uwmuhltx.html