前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot 全局异常处理

SpringBoot 全局异常处理

作者头像
jwangkun
发布2021-12-23 17:16:33
3280
发布2021-12-23 17:16:33
举报
文章被收录于专栏:John Wong's BlogJohn Wong's Blog

在开发中,我们经常会使用try/catch块来捕获异常进行处理,如果有些代码中忘记捕获异常或者不可见的一些异常出现,就会响应给前端一些不友好的提示,这时候我们可以使用全局异常处理。这样就不用在代码中写那些烦人的try/catch块了,代码的可读性也会提高。

SpringBoot提供的的注解@ControllerAdvice表示开启全局异常捕获,在自定义的异常方法上使用ExceptionHandler来进行统一处理。

下面一起看看如何优雅的处理全局异常!

一 定义响应状态码及信息的枚举类

代码语言:javascript
复制
@Getter
public enum CodeEnum {
    
    SUCCESS(0,"请求成功"),
    ERROR(500,"未知异常"),
    ERROR_EMPTY_RESULT(1001,"查询结果为空"),
    ERROR_INCOMPLETE_RESULT(1002,"请求参数不全");
    
    private int code;
    private String message;
    CodeEnum(int code,String message){
        this.code = code;
        this.message = message;
    }
}

二 定义响应数据的实体类

代码语言:javascript
复制
@Slf4j
@Data
public class R<T> implements Serializable {

    private static final long serialVersionUID = 572235155491705152L;
    /**
     * 响应的状态码
     */
    private int code;
    /***
     * 响应的信息
     */
    private String message;
    /**
     * 响应数据
     */
    private T data;

    /**
     * 放入响应码并返回
     * @param code
     * @param msg
     * @return
     */
    public R fillCode(int code,String msg){
        this.code = code;
        this.message = msg;
        return this;
    }

    /**
     * 放入响应码并返回
     * @param codeEnum
     * @return
     */
    public R fillCode(CodeEnum codeEnum){
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMessage();
        return this;
    }

    /**
     * 放入数据并响应成功状态
     * @param data
     * @return
     */
    public R fillData(T data){
        this.code = CodeEnum.SUCCESS.getCode();
        this.message = CodeEnum.SUCCESS.getMessage();
        this.data = data;
        return this;
    }
}

三 自定义两个异常

根据业务需求自定义异常,在本文中我定义了两个异常,分别用作响应结果为空时处理和请求参数错误时处理。

代码语言:javascript
复制
@Data
public class EmptyResutlException extends RuntimeException {

    private static final long serialVersionUID = -8839210969758687047L;
    private int code;
    private String message;

    public EmptyResutlException(CodeEnum codeEnum){
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMessage();
    }
}
@Data
public class RequestParamException extends RuntimeException {

    private static final long serialVersionUID = 4748844811214637041L;
    private int code;
    private String message;

    public RequestParamException(CodeEnum codeEnum){
        this.code = codeEnum.getCode();
        this.message = codeEnum.getMessage();
    }
}

四 定义全局异常处理类

由于这里我想要响应的结果为实体类对象,因此我直接用@RestControllerAdvice来代替了@ControllerAdvice,这两个注解的差别跟@Controller@RestController一样,rest的响应体为json格式的数据。

代码语言:javascript
复制
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 查询结果为空时处理
     * @param e
     * @return
     */
    @ExceptionHandler(EmptyResutlException.class)
    public R emptyResultExceptionHandler(EmptyResutlException e){
        log.error("查询结果为空:{}",e.getMessage());
        R result = new R();
        result.fillCode(e.getCode(),e.getMessage());
        return result;
    }

    /**
     * 请求参数错误时处理
     * @param e
     * @return
     */
    @ExceptionHandler(RequestParamException.class)
    public R requestParamExceptionHandler(RequestParamException e){
        log.error("请求参数不合法:{}",e.getMessage());
        R result = new R();
        result.fillCode(e.getCode(),e.getMessage());
        return result;
    }

    /**
     * 处理其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R exceptionHandler(Exception e){
        log.error("未知异常:{}",e.getMessage());
        R result = new R();
        result.fillCode(CodeEnum.ERROR);
        return result;
    }
}

五 自定义接口测试异常

代码语言:javascript
复制
@RestController
public class TestController {

    @GetMapping("getString")
    public R getString(String name){

        if(StringUtils.isEmpty(name)){
            throw new RequestParamException(1002,"请求参数name为空");
        }else if ("Java旅途".equals(name)) {
            // 这里没有查询操作,当请求参数是Java旅途的时候,模拟成查询结果为空
            throw new EmptyResutlException(1001,"查询结果为空");
        }
        // 这里模拟一下除自定义异常外的其他两种异常
        int i = 0;
        i = 5/i;
        return new R().fillData(name);
    }
}

在实际开发中可以自定义响应状态码的枚举类和自定义异常以满足需求。

下一篇: SpringBoot实现多文件上传→

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 定义响应状态码及信息的枚举类
  • 二 定义响应数据的实体类
  • 三 自定义两个异常
  • 四 定义全局异常处理类
  • 五 自定义接口测试异常
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档