Spring Boot @RestControllerAdvice 全局异常处理

利用注解@RestControllerAdvice 轻轻松松实现全局异常处理

一、定义统一响应体

package com.zhh.demo.common.response;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @Description: 接口出参统一响应实体
 * @Author: zhaoheng
 * @CreateTime: 2022-08-05  16:27
 */
@Data
@ApiModel("接口出参统一响应实体")
public class Response<T> implements Serializable {
    private static final long serialVersionUID = 3692286106860121474L;

    @ApiModelProperty(value = "状态码")
    private String code;

    @ApiModelProperty(value = "说明")
    private String message;

    private T data;

    public Response(){}

    public Response(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public Response(String code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}
package com.zhh.demo.common.response;

import lombok.Getter;

/**
 * @Description: 统一响应code和说明
 * @Author: zhaoheng
 * @CreateTime: 2022-08-05  16:42
 */
public enum ResponseCode {

    /** 通用码 **/
    FAIL("-1", "系统错误"),
    OK("200", "成功"),

    /**
     * 参考阿里巴巴开发手册
     * 错误码为字符串类型,共5位,分两部分组成:错误标识+4位数字编号。
     * 例:A0001,A1001,B0001,C0001... A、B、分别代表不通业务或者来源
     **/

    /** 参数校验不通过 **/
    PARAMETER_CHECK_FAILS("A0001","参数校验不通过"),

    /** 用户相关 A1xxx **/
    USER_NAME_NONSTANDARD("A1002", "用户名不合规");

    ResponseCode(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Getter
    private String code;

    @Getter
    private String msg;
}
package com.zhh.demo.common.response;

import com.zhh.demo.entity.common.ResponsePage;

import java.util.List;

/**
 * @Description: 接口统一响应实体构造类
 * @Author: zhaoheng
 * @CreateTime: 2022-08-05  16:37
 */
public class ResponseFactory {

    /**
     * 默认成功
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Response<T> success(T t){
       return new Response<T>(ResponseCode.OK.getCode(),ResponseCode.OK.getMsg(),t);
    }

    /**
     * 成功
     * @param responseCode  响应code和说明
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Response<T> success(ResponseCode responseCode, T t){
        return new Response<T>(responseCode.getCode(),responseCode.getMsg(),t);
    }

    /**
     * 成功
     * @param responseCode  响应code和说明
     * @return
     */
    public static <T> Response<T> success(ResponseCode responseCode){
        return new Response<T>(responseCode.getCode(),responseCode.getMsg());
    }

    /**
     * 默认失败
     * @param <T>
     * @return
     */
    public static <T> Response<T> error(){
        return new Response<T>(ResponseCode.FAIL.getCode(),ResponseCode.FAIL.getMsg());
    }

    /**
     * 失败
     * @param responseCode  响应code和说明
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Response<T> error(ResponseCode responseCode, T t){
        return new Response<T>(responseCode.getCode(),responseCode.getMsg(),t);
    }

    /**
     * 失败
     * @param responseCode  响应code和说明
     * @return
     */
    public static <T> Response<T> error(ResponseCode responseCode){
        return new Response<T>(responseCode.getCode(),responseCode.getMsg());
    }

    /**
     * 失败
     * @param code  错误码
     * @param msg   说明
     * @param t     响应数据
     * @param <T>
     * @return
     */
    public static <T> Response<T> error(String code, String msg, T t){
        return new Response<T>(code,msg,t);
    }

    /**
     * 失败
     * @param code  错误码
     * @param msg   说明
     * @return
     */
    public static <T> Response<T> error(String code, String msg){
        return new Response<T>(code,msg);
    }

    public static <T> ResponsePage pageResult(List<T> list, int total){
        return new ResponsePage<T>(list,total);
    }

}

二、定义全局异常处理类

package com.zhh.demo.common.exception;

import com.zhh.demo.common.response.Response;
import com.zhh.demo.common.response.ResponseCode;
import com.zhh.demo.common.response.ResponseFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * @Description: 全局异常处理
 * @Author: zhaoheng
 * @CreateTime: 2022-08-05  17:33
 */
@Slf4j
@RestControllerAdvice
public class ExceptionHandle {

    /**
     * 处理Exception异常
     * @param exception 异常类型
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Response<?> ExceptionHandle(Exception exception){
        log.error("系统出现异常:",exception);
        return ResponseFactory.error(ResponseCode.FAIL);
    }

    /**
     * 处理业务异常
     * @param exception 异常类型
     * @return
     */
    @ExceptionHandler(value = BaseException.class)
    public Response<?> BaseExceptionHandle(BaseExceptionexception){
        log.error("系统业务异常:",exception);
        return ResponseFactory.error(exception.getCode(),exception.getMsg());
    }

    /**
     * 入参校验异常,校验不通过,抛出异常信息
     * @param exception Valid 入参校验异常
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Response<?> methodArgumentNotValidExceptionHandle(MethodArgumentNotValidException exception){
        log.error("入参校验不通过",exception);
        BindingResult bindingResult = exception.getBindingResult();
        List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
        fieldErrorList.forEach(fieldError -> {
            log.info("字段:{},message:{}",fieldError.getField(),fieldError.getDefaultMessage());
        });
        // 一个一个给调用方返回提示
        String message = fieldErrorList.get(0).getDefaultMessage();
        return ResponseFactory.error(ResponseCode.PARAMETER_CHECK_FAILS.getCode(), message);
    }

}

自定义异常

package com.zhh.demo.common.exception;

import com.zhh.demo.common.response.Response;
import com.zhh.demo.common.response.ResponseCode;
import lombok.Data;

/**
 * @Description: 异常基类
 * @Author: zhaoheng
 * @CreateTime: 2022-08-05  17:22
 */
@Data
public abstract class BaseException extends RuntimeException{

    /**
     * code码
     */
    private String code;

    /**
     * 异常说明
     */
    private String msg;

    /**
     * 响应体
     */
    private Response response;

    public BaseException(String code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
        this.response = new Response(code,msg);
    }

    public BaseException(ResponseCode responseCode) {
        super(responseCode.getMsg());
        this.code = responseCode.getCode();
        this.msg = responseCode.getMsg();
        this.response = new Response(responseCode.getCode(),responseCode.getMsg());
    }
}

三、编写接口测试效果

package com.zhh.demo.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;


@Api(tags = "test-api")
@RequestMapping("/api/test")
@RestController
@Validated // 开启入参校验
public class TestController {
    
    @ApiOperation("异常测试")
    @PostMapping("/t1")
    public String test(){
        // 模拟异常
        new ArrayList<>().get(1);
        return "";
    }
}

经过测试,接口抛出异常后会被异常处理类处理,并且给调用端返回指定格式的提示信息

{
  "code": "-1",
  "message": "系统错误",
  "data": null
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值