背景
使用spring cloud搭建微服务时,我们会定义自己的返回对象,设置返回code,msg,data,便于调用方解析,统一格式也便于为大型项目编写client库。正常返回时没问题,那如果接口服务抛exception,或者controller验证不通过时该如何catch住异常返回对应报错并包装为自己的返回对象。
解决
/**
* 自动捕获异常联动返回
* 所有捕获到的异常HTTP返回状态码都要为200,不然很多client会认为http失败而不打印我们自己的报错
* @author: zhangjikuan
* @Date: 2021/1/4 11:11
*/
@RestControllerAdvice
public class GlobalExceptionAdvice {
/**
* 参数错误的异常捕获
* @param e e
* @return PaasResult
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.OK)
public PaasResult<String> paramMissingException(MissingServletRequestParameterException e) {
e.printStackTrace();
return PaasResult.fail(PaasResultCode.INVALID_PARAMETER.getCode(), e.getMessage());
}
/**
* 参数错误的异常捕获
* @param e e
* @return PaasResult
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.OK)
public PaasResult<String> paramInvalidException(MethodArgumentNotValidException e) {
e.printStackTrace();
return PaasResult.fail(PaasResultCode.INVALID_PARAMETER.getCode(), e.getMessage());
}
/**
* 只针对@Validated的异常,比如@NotBlank @NotNull @NotEmpty这种
* @param e
* @return
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.OK)
public PaasResult<String> paramValidationException(ConstraintViolationException e) {
e.printStackTrace();
return PaasResult.fail(PaasResultCode.INVALID_PARAMETER.getCode(), e.getMessage());
}
/**
* 未知异常的捕获
* @param e e
* @return PaasResult
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.OK)
public PaasResult<String> exception(Exception e) {
e.printStackTrace();
return PaasResult.fail(PaasResultCode.UNKNOWN_ERROR.getCode(), e.getMessage());
}
}
注意:@ResponseStatus(HttpStatus.OK) 设置的是http返回状态码,很多client会解析此状态,如果状态不是200就直接抛异常,不会再拿我们封装的返回值,所以最好设置为200
当时因为这里出现问题排查耗费了些时间:https://blog.csdn.net/zhangjikuan/article/details/115005905
PaasResult是我自己封装的返回结构