spring-boot-route(四)全局异常处理

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

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

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

一 定义响应状态码及信息的枚举类
@Getter
public enum CodeEnum {spring

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;
}

}
二 定义响应数据的实体类
@Slf4j
@Data
public class R<T> implements Serializable {json

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;
}

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

@Data
public class EmptyResutlException extends RuntimeException {app

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 {spring-boot

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格式的数据。学习

@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;
}

}
五 自定义接口测试异常
@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);
}

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

此是spring-boot-route系列的第四篇文章,这个系列的文章都比较简单,主要目的就是为了帮助初次接触Spring Boot 的同窗有一个系统的认识。本文已收录至个人github,欢迎各位小伙伴star!

github:https://github.com/binzh303/s...

点关注、不迷路
若是以为文章不错,欢迎关注、点赞、收藏,大家的支持是我创做的动力,感谢你们。

若是文章写的有问题,请不要吝啬,欢迎留言指出,我会及时核查修改。

若是你还想更加深刻的了解我,能够微信搜索「Java旅途」进行关注。回复「1024」便可得到学习视频及精美电子书。天天7:30准时推送技术文章,让你的上班路不在孤独,并且每个月还有送书活动,助你提高硬实力!

相关文章
相关标签/搜索