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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682742.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

客户端被攻击怎么办,为什么应用加速这么适合

随着科技的进步和互联网的普及&#xff0c;游戏行业也正在经历前所未有的变革。玩家们不再满足于传统的线下游戏&#xff0c;而是转向了线上游戏。然而&#xff0c;随着游戏的线上化&#xff0c;游戏安全问题也日益凸显。游戏受到攻击是游戏开发者永远的痛点&#xff0c;谈“D“…

QtCharts使用

1.基础配置 1.QGraphicsView提升为QChartView#include <QtCharts> QT_CHARTS_USE_NAMESPACE #include "ui_widget.h"2. QT charts 2.柱状图 2.1QBarSeries //1.创建Qchart对象QChart *chart new QChart();chart->setTitle("直方图演示");//设…

回炉重造java----JUC(第二天)

Monitor---监视器/管程 对象头&#xff1a; 操作系统提供的Monitor对象 Synchronized底层实现原理&#xff1a; ①锁对象在加了synchronized之后&#xff0c;对象头中的Mark Word中就存了一个Monitor的地址指针。 ②当一个线程获取到锁之后&#xff0c;Monitor中的Owner属性指…

C++青少年简明教程:字符类型、字符数组和字符串

C青少年简明教程&#xff1a;字符类型、字符数组和字符串 在 C 语言中&#xff0c;处理文本数据的基础是字符类型 char&#xff0c;字符数组&#xff0c;以及标凌库中的字符串类 std::string。 C中的char类型占用 1 字节的内存空间&#xff0c;用于存储单个ASCII字符。例如&a…

ChatTTS web应用;基于文本指导的图像生成;使用Groq和Llama3在几秒内生成整本书;协作机器人画家,可以根据语言描述或图像在画布上作画

✨ 1: ChatTTS-Nuxt3 Webui ChatTTS-Nuxt3 WebUI是基于ChatTTS开发的文本转语音Web应用&#xff0c;支持详细参数调整和移动视图。 ChatTTS-Nuxt3 Webui 基于 ChatTTS 项目开发&#xff0c;由 2noise 创建&#xff0c;WebUI 开发则由 Gouryella 完成。你可以在 这里 免费试用…

C语言数字全排列生成器

前言 从0开始记录我的学习历程&#xff0c;我会尽我所能&#xff0c;写出最最大白话的文章&#xff0c;希望能够帮到你&#xff0c;谢谢。 提示&#xff1a;文章作者为初学者&#xff0c;有问题请评论指正&#xff0c;感谢。 这个代码的功能是生成并打印出从1到N的所有整数的…

zdppy_amauth 实现给角色批量绑定权限

新增接口 api.resp.post("/auth/role_auth", amauth.role.add_auths)如何测试 如何测试能不能给指定的角色批量的添加权限呢&#xff1f; 1、需要新建一个角色2、需要拿到这个角色的ID3、需要新增三个权限4、需要拿到新增的三个权限的ID5、拿着角色ID和权限ID列表…

通信技术振幅键控(ASK)调制与解调硬件实验

一、实验目的 1. 掌握用键控法产生ASK信号的方法&#xff1b; 2. 掌握ASK非相干解调的原理。 二、实验内容 1. 观察ASK已调信号的波形&#xff1b; 2. 观察ASK解调信号的波形。 三、实验器材 1. 双踪示波器&#xff1b; 2. 通信原理实验箱信号源模块、③、④、⑦号模块。…

输出流--6.6

代码以及解释&#xff1a; package java2;import java.io.File; import java.io.FileWriter; import java.io.IOException;public class Test02 {public static void main(String[] args) throws IOException {String str "flag{hello_ctf}";//1.封装File fnew Fil…

Locality-aware subgraphs for inductive link prediction in knowledge graphs

Locality-aware subgraphs for inductive link prediction in knowledge graphs a b s t r a c t 最近的知识图&#xff08;KG&#xff09;归纳推理方法将链接预测问题转化为图分类任务。 他们首先根据目标实体的 k 跳邻域提取每个目标链接周围的子图&#xff0c;使用图神经网…

鸿蒙轻内核M核源码分析系列六 任务及任务调度(2)任务模块

任务是操作系统一个重要的概念&#xff0c;是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它任务运行。鸿蒙轻内核的任务模块可以给用户提供多个任务&#xff0c;实现任务间的切换&#xff0c;帮助用户管理业务程序流程。…

鸿蒙北向开发 IDE DevEco Studio 3.1 傻瓜式安装闭坑指南

首先下载 安装IDE 本体程序 DevEco Studio 下载链接 当前最新版本是3.1.1,下载windows版本的 下载下来后是一个压缩包, 解压解锁包后会出现一个exe安装程序 双击运行安装程序 一路 next ( 这里涉及安装文件目录,我因为C盘够大所以全部默认了,各位根据自己情况选择自己的文件…

我的创作纪念日--我和CSDN一起走过的1825天

机缘 第一次在CSDN写文章&#xff0c;是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记&#xff0c;没有去和大家区分享的想法&#xff0c;是一起的朋…

MotionEditor_ 通过内容感知扩散编辑视频运动

图1. MotionEditor&#xff1a;一种基于扩散的视频编辑方法&#xff0c;旨在将参考视频的运动转移到源视频中。 摘要 现有的基于扩散的视频编辑模型在随时间编辑源视频的属性方面取得了显著进展&#xff0c;但在修改运动信息的同时保持原始主角的外观和背景方面存在困难。为…

WordPress 插件推荐:菜单缓存插件——Menu Caching

今天在缙哥哥博客上发现了一个 WordPress 速度优化插件的优化感觉很不错&#xff0c;明月自己装上也体验了一番&#xff0c; WordPress 菜单的载入速度无论是 PC 端和移动端都非常不错&#xff0c;并且这个叫 Menu Caching 的菜单缓存插件还完美的兼容 WPRocket&#xff0c;W3 …

三.一布局和布局切换的实践与探索

在前端开发中&#xff0c;灵活的布局切换是一项非常实用的功能。今天&#xff0c;我想和大家分享一下如何在主组件中通过更换 Layout 目录下的组件来实现布局切换。 首先&#xff0c;我们有一个主组件 index.vue&#xff0c;它承担着整个页面的主要逻辑和展示。 而在 Layout …

PHP序列化、反序列化

目录 一、PHP序列化&#xff1a;serialize() 1.对象序列化 2.pop链序列化 3.数组序列化 二、反序列化&#xff1a;unserialize() 三、魔术方法 ​四、NSSCTF相关简单题目 1.[SWPUCTF 2021 新生赛]ez_unserialize 2.[SWPUCTF 2021 新生赛]no_wakeup 学习参考&#xff1…

使用 Logback.xml 配置文件输出日志信息

官方链接&#xff1a;Chapter 3: Configurationhttps://logback.qos.ch/manual/configuration.html 配置使用 logback 的方式有很多种&#xff0c;而使用配置文件是较为简单的一种方式&#xff0c;下述就是简单描述一个 logback 配置文件基本的配置项&#xff1a; 由于 logba…

优化 mac 储存空间的方法 只需一招为你的苹果电脑提速

在职场中&#xff0c;许多人都对苹果电脑情有独钟。苹果电脑以其简洁美观的设计、流畅稳定的性能以及出色的用户体验&#xff0c;成为了众多职场人士的得力助手。无论是处理文档、制作演示文稿&#xff0c;还是进行创意设计等工作&#xff0c;苹果电脑都能展现出其独特的优势&a…

HCIP-Datacom-ARST自选题库__多种协议简答【11道题】

1.BGP/MPLSIP VPN的典型组网场景如图所示&#xff0c;PE1和PE2通过LoopbackO建立MP-IBGP&#xff0c;PE1和PE2之间只传递VPN路由&#xff0c;其中PE1BGP进程的部分配置已在图中标出&#xff0c;则编号为0的命令不是必须的。(填写阿拉伯数字) 3 2.在如图所示的Hub&amp;Spok…