在编写REST接口时,常常会抛出各种各样的异常,比如系统错误,请求参数不合法,没有权限,token检验未通过等等,这时如果直接抛出异常,不仅对使用者不友好,而且会暴露程序内部信息,这种做法是不可取的,程序可以对异常进行拦截,并进一步封装。同时,对于程序异常,如果有一整套异常码以及对应的异常信息,那么也非常便于排查异常。下面就来介绍一下基于拦截器实现全局异常拦截。
一、定义接口返回包装类BaseResponse
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse implements Serializable {
private int code;
private String message;
private T data;
public BaseResponse(T data) {
this.code = 0;
this.data = data;
this.message = "OK";
}
public BaseResponse(int code, String message) {
this.code = code;
this.message = message;
}
}
二、定义全局异常类BizException
@Data
@EqualsAndHashCode(callSuper = true)
public class BizException extends RuntimeException {
private int code;
public BizException(Integer code, String message) {
super(message);
this.code = code;
}
public BizException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
三、定义全局异常码以及异常信息(异常码与异常信息视业务而定,这里只列举几个做示例)
public enum SystemEvent {
/**
* 异常类型及异常码定义
*/
INVALID_PARAM(10000, "接口输入参数不合法"),
SYSTEM_ERROR(10002, "系统异常,操作失败"),
NOT_FOUND(10110, "没有找到数据"),
PASSWORD_ERROR(10111,"用户名或密码错误"),
INVALID_TOKEN(999999, "token无效");
private Integer id;
private String details;
SystemEvent(Integer id, String details) {
this.id = id;
this.details = details;
}
public Integer getId() {
return this.id;
}
public String getDetails() {
return details;
}
}
四、定义全局异常拦截器
@ResponseBody
@ControllerAdvice(basePackages = "com.shuwei.userprofile.web.controller")
public class ExceptionInterceptor extends ResponseEntityExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionInterceptor.class);
/**
* Hibernate validate 失败的异常.
*/
@Override
protected ResponseEntity
这样就实现了全局异常拦截,所有抛出的异常都会被这个拦截器拦截并进一步封装转化为异常码和异常信息,如下图: