知识碎片-SpringBoot统一返回结果和捕获异常

本文介绍了如何在SpringMVC应用中定义统一的返回结果类ResultResponse,使用新注解ResponseResult,以及如何通过ResponseBodyAdvice实现Controller的返回结果转换为JSON格式。同时,还讨论了如何捕获并处理自定义异常和常见错误。
摘要由CSDN通过智能技术生成

统一返回结果

  1. 定义统一返回结果类ResultResponse
  2. 定义新注解@ResponseResult来标记需要拦截的方法或类
  3. 添加RestControllerAdvice注解,实现ResponseBodyAdvice接口,重写support, beforeBodyWrite方法

统一结果类ResultResponse

@Setter
@Getter
public class ResultResponse<T> {

    /**
     * 响应代码
     */
    private String code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应结果
     */
    private T result;

    public ResultResponse() {
    }

    public ResultResponse(BaseErrorInfoInterface errorInfo) {
        this.code = errorInfo.getResultCode();
        this.message = errorInfo.getResultMsg();
    }

    /**
     * 成功
     */
    public static <T> ResultResponse<T> success() {
        return success(null);
    }

    /**
     * 成功
     */
    public static <T> ResultResponse<T> success(T data) {
        ResultResponse<T> rb = new ResultResponse<>();
        rb.setCode(ExceptionEnum.SUCCESS.getResultCode());
        rb.setMessage(ExceptionEnum.SUCCESS.getResultMsg());
        rb.setResult(data);
        return rb;
    }

    /**
     * 失败
     */
    public static <T> ResultResponse<T> error(BaseErrorInfoInterface errorInfo) {
        ResultResponse<T> rb = new ResultResponse<>();
        rb.setCode(errorInfo.getResultCode());
        rb.setMessage(errorInfo.getResultMsg());
        rb.setResult(null);
        return rb;
    }

    /**
     * 失败
     */
    public static <T> ResultResponse<T> error(String code, String message) {
        ResultResponse<T> rb = new ResultResponse<>();
        rb.setCode(code);
        rb.setMessage(message);
        rb.setResult(null);
        return rb;
    }

    /**
     * 失败
     */
    public static <T> ResultResponse<T> error(String message) {
        ResultResponse<T> rb = new ResultResponse<>();
        rb.setCode("-1");
        rb.setMessage(message);
        rb.setResult(null);
        return rb;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }

}

定义新注解ResponseResult

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface ResponseResult {
}

ResponseResultBodyAdvice类

  1. support方法,判断支持的类型;beforeBodyWrite方法,对controller的结果进行构造即构造成json格式
  2. RestControllerAdvice注解=ResponseBody+ControllerAdvice
@RestControllerAdvice
@Slf4j
public class ResponseResultBodyAdvice implements ResponseBodyAdvice<Object> {

    @Resource
    private ObjectMapper objectMapper;

    private static final Class<? extends Annotation> ANNOTATION_TYPE = ResponseResult.class;

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ANNOTATION_TYPE) || returnType.hasMethodAnnotation(ANNOTATION_TYPE);
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        // 如果返回类型是string,那么springmvc是直接返回的,此时需要手动转化为json
        Class<?> returnClass = returnType.getMethod().getReturnType();
        if (body instanceof String || Objects.equals(returnClass, String.class)) {
            return objectMapper.writeValueAsString(ResultResponse.success(body));
        }
        // 防止重复包裹的问题出现
        if (body instanceof ResultResponse) {
            return body;
        }
        return ResultResponse.success(body);
    }
}

统一捕获异常

@ExceptionHandler(value = BizException.class) 捕获自定义异常

@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理自定义的业务异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResultResponse<Void> bizExceptionHandler(HttpServletRequest req, BizException e) {
        logger.error("发生业务异常!原因是:{}", e.getErrorMsg());
        return ResultResponse.error(e.getErrorCode(), e.getErrorMsg());
    }

    /**
     * 处理空指针的异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public ResultResponse<Void> exceptionHandler(HttpServletRequest req, NullPointerException e) {
        logger.error("发生空指针异常!原因是:", e);
        return ResultResponse.error(ExceptionEnum.BODY_NOT_MATCH);
    }

    /**
     * 处理其他异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultResponse<Void> exceptionHandler(HttpServletRequest req, Exception e) {
        logger.error("未知异常!原因是:", e);
        return ResultResponse.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WeiXiao_Hyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值