hutool工具实践-验证码

简介  

验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:

  • createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
  • getCode 获取验证码的文字内容
  • verify 验证验证码是否正确,建议忽略大小写
  • write 将验证码图片写出到目标流中

其中write方法只有一个OutputStreamICaptcha实现类可以根据这个方法封装写出到文件等方法。

AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。

ps:国产的工具库,值得支持

官网地址:Hutool🍬一个功能丰富且易用的Java工具库,涵盖了字符串、数字、集合、编码、日期、文件、IO、加密、数据库JDBC、JSON、HTTP客户端等功能。

依赖引入

<dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.17</version>
</dependency>

使用示例

线段干扰验证码

    @Test
    public void lineCaptchaTest() {
        //定义图形验证码的长和宽
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);

        //图形验证码写出,可以写出到文件,也可以写出到流
        captcha.write("d:/line.png");

        //输出code
        Console.log(captcha.getCode());

        //验证图形验证码的有效性,返回boolean值
        captcha.verify("1234");
    }

生产的验证形如:

圆圈干扰验证码

    @Test
    public void circleCaptchaTest() {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(800, 400);
        //CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);

        //图形验证码写出,可以写出到文件,也可以写出到流
        captcha.write("d:/circle.png");

        Console.log(captcha.getCode());

        //验证图形验证码的有效性,返回boolean值
        printVerify("1234",captcha);
    }

生成的验证码形如:

扭曲干扰验证码

    @Test
    public void circleCaptchaTest() {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(800, 400);
        //CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);

        //图形验证码写出,可以写出到文件,也可以写出到流
        captcha.write("d:/circle.png");

        Console.log(captcha.getCode());

        //验证图形验证码的有效性,返回boolean值
        printVerify("1234",captcha);
    }

生成的验证码形如:

verify代码

private void printVerify(String verifyCode, AbstractCaptcha captcha) {
        Console.log("验证结果是:" + captcha.verify(verifyCode));
    }

说明

1  框架验证默认使用的生成器是:RandomGenerator(随机数生成器),可以指定运算生成器,甚至自定义验证码生成器(实现CodeGenerator接口即可)

2 生成的验证码是存储在内存中的,后续要做输入验证需要使用同一个ICaptcha验证(当然也可以把验证码存储在其他地方,比如redis,然后标记一下,后续验证只要能取到对应的验证做验证即可)

实践案例

        验证码的使用主要在登录和各种操作需要验证密码的场景下,以下是一个简单的登录验证码的使用

1  创建接口生产验证码图片

    @GetMapping("captCha")
    public R<CaptchaVo> captCha() {
        CaptchaVo captchaVo = new CaptchaVo();
        captchaVo.setImg(diyMath());
        return R.success(captchaVo);
    }

    public String diyMath() {
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 45, 1, 4);
        // 自定义验证码内容为四则运算方式
        captcha.setGenerator(new MathGenerator());
        // 重新生成code
        captcha.createCode();
        String code = captcha.getCode();
        Console.log("运算生成的验证码是:" + code);
        return captcha.getImageBase64();
    }
/**
 * 验证码信息
 */
@Data
public class CaptchaVo {

    private String uuid;

    /**
     * 验证码图片
     */
    private String img;

}

2 在html页面中通过<img src = "">标签渲染图片

function createCodeImg(domElement) {
    debugger;
    let uri = "/captCha"
    let request = new XMLHttpRequest();
    // 2、建立连接
    // true:请求为异步  false:同步
    request.open("GET", uri, false);
    request.send();
    let resSource = request.responseText;
    let response  = JSON.parse(request.responseText);

    // 设置img元素的src属性为创建的URL
    document.getElementById('loginImg').src = "data:image/gif;base64," + response.data.img;
}

这里通过get请求获取后端接口数据,在后端返回的图片信息时,返回的是图片的Base64数据信息,形如:

在前端直接通过该dom元素的src属性就可以渲染出来

为了保证在后续的登录验证时能校验验证码,后端回传了一个uuid到前端,作为绑定验证码的唯一凭据,验证码的数据是存储在redis中。在之后的登录验证时,前端将验证码关联的唯一凭据和验证码结果一起传给后端,后端通过唯一凭据查询redis,完成验证码的校验流程

如何计算结果

通过RandomGenerator生成的验证码无需计算,直接存储在redis中即可,如果是MathGenerator生成的验证码是需要计算结果的,如何获取计算结果呢?

hutool提供的工具:Calculator

    @Test
    public void mathStrCount() {
        String testCode = "12*13";
        double conversion = Calculator.conversion(testCode);
        Console.log(conversion);
    }

计算结果是:156.0

spring提供的工具:ExpressionParser

    @Test
    public void mathSpringCount() {
        String testCode = "12*13";
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(testCode);
        String result = exp.getValue(String.class);
        Console.log(result);
    }

计算结果是:156

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值