4.0 KiB
4.0 KiB
在某些情况下,对入参中的字段进行参数校验时,没有办法用到校验注解,如登录接口中验证码的判空。因为这个接口是个二合一接口,需要同时支持手机号验证码登录,以及账号密码登录。只能在业务层中,手动进行参数校验,如下图所示:
现在就校验一个字段,你会感觉代码还不是太难看。试想一下,当有多个字段需要校验时,就会有一堆的 if 判断,伪代码如下:
// 校验入参验证码是否为空
if (StringUtils.isBlank(verificationCode)) {
return Response.fail(ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode(), "验证码不能为空");
}
// 参数校验2
if (条件判断2) {
return Response.fail(ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode(), "xxx");
}
// 参数校验3
if (条件判断3) {
return Response.fail(ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode(), "xxx");
}
// 省略...
那么,有优化的方法吗? 看着很丑陋 ! 本小节中,我们就将使用谷歌 Guava 库中的 Preconditions 工具类,搭配全局异常捕获,来将这块的代码重构一下。
Guava 库中的 Preconditions
Guava 是一个广泛使用的 Java 库,提供了许多有用的工具和实用程序,其中包括参数校验工具。Guava 的参数校验功能主要通过 com.google.common.base.Preconditions 类来实现。Preconditions 提供了一组静态方法,用于在方法执行前验证参数的有效性。这些方法在条件不满足时抛出异常,从而确保方法得到合法的输入。
开始使用
将之前的 if 验证码校验代码删除掉,改用 Preconditions , 代码如下:
// 省略...
// 校验入参验证码是否为空
Preconditions.checkArgument(StringUtils.isNotBlank(verificationCode), "验证码不能为空");
// 省略...
3 行代码变成 1 行,清爽多了 !!!
搭配全局异常捕获
光这样还不行,查看一下 checkArgument() 方法的源码,如下:
可以看到,该方法会主动抛出一个 IllegalArgumentException 异常。编辑 GlobalExceptionHandler 全局异常捕获类,对该异常进行捕获,并统一处理:
代码如下:
// 省略...
/**
* 捕获 guava 参数校验异常
* @return
*/
@ExceptionHandler({ IllegalArgumentException.class })
@ResponseBody
public Response<Object> handleIllegalArgumentException(HttpServletRequest request, IllegalArgumentException e) {
// 参数错误异常码
String errorCode = ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode();
// 错误信息
String errorMessage = e.getMessage();
log.warn("{} request error, errorCode: {}, errorMessage: {}", request.getRequestURI(), errorCode, errorMessage);
return Response.fail(errorCode, errorMessage);
}
// 省略...
- 错误异常码,统一使用已经定义好的
PARAM_NOT_VALID参数错误枚举;- 通过
e.getMessage()拿到异常提示信息;- 返回响应数据;
自测一波
代码重构完毕后,重启项目,再来测试一波登录接口,将验证码填写为空字符串,如下图所示:
可以看到,错误码为 AUTH-10001 , 提示信息为验证码不能为空。OK , 代码重构完毕。