weblog/doc/5、整合 SaToken 实现 JWT 登录功能/5.14 代码优化:Guava Preconditions 参数校验.md
2025-02-17 10:05:44 +08:00

4.0 KiB
Raw Blame History

在某些情况下,对入参中的字段进行参数校验时,没有办法用到校验注解,如登录接口中验证码的判空。因为这个接口是个二合一接口,需要同时支持手机号验证码登录,以及账号密码登录。只能在业务层中,手动进行参数校验,如下图所示:

现在就校验一个字段,你会感觉代码还不是太难看。试想一下,当有多个字段需要校验时,就会有一堆的 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 , 代码重构完毕。

本小节源码下载

https://t.zsxq.com/U2nrD