java:实现简单的验证码功能
效果
实现思路
验证码图片的url由后端的一个Controller生成,前端请求这个Controller接口的时候根据当前时间生成一个uuid,并把这个uuid在前端使用localStorage缓存起来,下一次还是从缓存中获取。
Controller生成验证码之后,把前端传过来的uuid通过redis缓存起来,这里分两次缓存
- 缓存uuid
- 以uuid为key,缓存验证码
这样,当点击登录按钮将数据提交到后台登录接口时,会从redis中获取uuid,然后通过这个uuid去获取验证码,和前端用户输入的验证码进行比较。
简单验证码
生成随机字符(如数字、字母)的字符串,并将这些字符绘制到一张图片上,最后输出这张图片。
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random; public class CaptchaGenerator { private static final int WIDTH = 100; private static final int HEIGHT = 40; private static final Random RANDOM = new Random(); public static void main(String[] args) { // 生成验证码文本 String captchaText = generateCaptchaText(6); // 生成验证码图片 File outputFile = new File("captcha.png"); generateCaptchaImage(captchaText, outputFile); System.out.println("Captcha generated: " + captchaText); } private static String generateCaptchaText(int length) { StringBuilder sb = new StringBuilder(length); for (int i = 0; i < length; i++) { // 随机选择字符类型 int type = RANDOM.nextInt(3); if (type == 0) { // 数字 sb.append(RANDOM.nextInt(10)); } else if (type == 1) { // 小写字母 sb.append((char) ('a' + RANDOM.nextInt(26))); } else { // 大写字母 sb.append((char) ('A' + RANDOM.nextInt(26))); } } return sb.toString(); } private static void generateCaptchaImage(String captchaText, File outputFile) { BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bufferedImage.createGraphics(); // 设置背景色 g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, WIDTH, HEIGHT); // 设置字体 Font font = new Font("Arial", Font.BOLD, 24); g2d.setFont(font); // 绘制验证码文本 g2d.setColor(Color.BLACK); FontMetrics fontMetrics = g2d.getFontMetrics(); int x = (WIDTH - fontMetrics.stringWidth(captchaText)) / 2; int y = ((HEIGHT - fontMetrics.getHeight()) / 2) + fontMetrics.getAscent(); g2d.drawString(captchaText, x, y); // 释放资源 g2d.dispose(); // 输出图片 try { ImageIO.write(bufferedImage, "png", outputFile); } catch (IOException e) { e.printStackTrace(); } }
}
工具包
- Hutool:是一个多功能的工具包,其中有验证码的功能hutool-captcha
- easy-captcha:专注验证码
Hutool demo
1、添加依赖
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version>
</dependency>
2、写一个控制器
package com.zhangyu.controller;import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.json.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;@RestController
public class CaptchaController {@GetMapping("/captcha")public Map captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {// 生成验证码图片 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100, 4, 4);// 获取验证码图片上的文字String captchaText = lineCaptcha.getCode();// 将验证码文字放入session,键名为 CAPTCHA_KEYrequest.getSession().setAttribute("CAPTCHA_KEY", captchaText);System.out.println("文字是" + captchaText);// 输出图片 BufferedImage image = lineCaptcha.getImage();// 图片转base64String base = ImageToBase64.convertImageToBase64(image);System.out.println("base文字是" + base);// 组装数据Map resultMap = new HashMap();resultMap.put("code", captchaText);resultMap.put("img", "data:image/png;base64," + base);return resultMap;}@PostMapping("/submit")public String submit(HttpServletRequest request, @RequestBody JSONObject jsonObject) {String captcha = jsonObject.getStr("captcha");String sessionCaptcha = (String) request.getSession().getAttribute("CAPTCHA_KEY");if (captcha.equalsIgnoreCase(sessionCaptcha)) {return "验证码正确!";} else {return "验证码错误,请重试!";}}
}
package com.zhangyu.controller;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.io.IOException;public class ImageToBase64 {public static String convertImageToBase64(BufferedImage image) throws IOException {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(image, "png", baos); // 可以改为需要的图片格式,如"jpg"byte[] imageBytes = baos.toByteArray();return Base64.getEncoder().encodeToString(imageBytes);}
}
3、前端测试
这里我用vue写了一个简单的demo
<template><div class="home"><img :src="imgUrl" @click="getCaptchaImg()" alt="captcha" title="点击刷新"><input type="text" name="captcha" placeholder="输入验证码" v-model="text"><button type="submit" @click="submitCaptcha()">提交</button></div>
</template><script>
import baseApi from '@/api/base'
export default {name: 'HomeView',data () {return {imgUrl: '',text: ''}},methods: {async getCaptchaImg() {const res = await baseApi.getCaptchaImg()this.imgUrl = res.img},async submitCaptcha() {const params = {captcha: this.text,}const res = await baseApi.submitCaptcha(params)}},async mounted () {this.getCaptchaImg()}
}
</script>
import ajax from '@/libs/ajax'const baseApi = {getCaptchaImg: () => ajax.request({url: '/captcha',method: 'get'}),submitCaptcha: (data) => ajax.request({url: '/submit',method: 'post',data})
}
export default baseApi
devServer: {port: 9001,open: false,// 配置跨域请求头,解决开发环境的跨域问题headers: {'Access-Control-Allow-Origin': '*',},proxy: 'http://192.168.18.21:9090/'
},
4、效果
总结
这里只是用Hutool工具包做了一个demo,easy-captcha我就不展示了也差不多。
真实的场景是返回给前端base64图片和一个uuid,并不是我这里展示的图片文字,然后提交的时候前端把uuid和输入内容传递给后端,由于我这里只是demo所以没有牵扯uuid
相关文章:

java:实现简单的验证码功能
效果 实现思路 验证码图片的url由后端的一个Controller生成,前端请求这个Controller接口的时候根据当前时间生成一个uuid,并把这个uuid在前端使用localStorage缓存起来,下一次还是从缓存中获取。 Controller生成验证码之后,把前…...

MybatisPlus使用指南
MybatisPlus 1. 快速入门1.1 入门案例1.2 常见注解1.3 常见配置 2. 核心功能2.1 条件构造器2.2 自定义SQL2.3 Service接口 3. 扩展功能3.1 代码生成3.2 静态工具3.3 逻辑删除 4. 插件功能4.1 分页插件4.2 通用分页实体 1. 快速入门 1.1 入门案例 步骤一:引入Mybat…...
5. MongoDB 集合创建、更新、删除
1. 创建集合 1.1 语法 db.createCollection(name, options) 参数说明: name: 要创建的集合名称。options: 可选参数, 指定有关内存大小及索引的选项。 options 可以是如下参数: 参数名类型描述示例值capped布尔值是否创建一个固定大小的集合。truesize…...
PHP中如何将变量从函数传递给acf_add_filter
在PHP开发中,我们有时需要将变量从函数传递给acf的add_filter钩子。这样做可以让我们在acf字段加载时,对字段值进行动态修改。下面,我将详细介绍如何实现这一功能。 在acf中,我们使用add_filter来添加钩子,对字段的加…...
KNN算法的使用
目录 一、KNN 算法简介 二、KNN算法的使用 1.读取数据 2.处理数据 三、训练模型 1.导入KNN模块 2.训练模型 3.出厂前测试 四、进行测试 1.处理数据 2.进行测试 总结 一、KNN 算法简介 KNN 是一种基于实例的学习算法。它通过比较样本之间的距离来进行预测。算法的核心…...

java文件上传
导入jar包,或者maven <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>…...
MySQL 数据库经验总结
一、数据库操作 1. 创建数据库 CREATE DATABASE database_name;例如,创建一个名为 my_database 的数据库: CREATE DATABASE my_database;2. 选择数据库 USE database_name;要使用刚才创建的 my_database 数据库: USE my_database;3. 删除…...

Python环境安装及PIP安装(Mac OS版)
官网 https://www.python.org/downloads/ 安装python python-3.12.1-macos11.pkg下载后,安装一直下一步即可 验证是否安装成功,执行python3命令和pip3命令 配置环境变量 获取python3安装位置并配置在.bash_profile #查看python路径 which python3#…...

2024自动驾驶(多模态)大模型综述:从DriveGPT4、DriveMLM到DriveLM、DriveVLM
前言 由于今年以来,一直在不断深挖具身智能机器人相关,而自动驾驶其实和机器人有着无比密切的联系,甚至可以认为,汽车就是一个带着4个轮子的机器人 加之个人认为,目前大模型落地潜力最大的两个方向,一个是…...

晨控CK-GW08-EC与汇川AC801系列PLC的EtherCAT通讯连接说明手册
晨控CK-GW08-EC与汇川AC801系列PLC的EtherCAT通讯连接说明手册 晨控CK-GW08-EC是一款支持标准工业通讯协议EtherCAT的网关控制器,方便用户集成到PLC等控制系统中。系统还集成了8路读写接口,用户可通过通信接口使用EtherCAT协议对8路读写接口所连接的读卡器进行相对…...

向上or向下调整建堆 的时间复杂度的本质区别的讲解
知识点:(N代表节点数,h代表高度) 1:高度为h的满二叉树节点个数N为 2^(h)-1 即N 2^(h)-1 2:所以h log(N1) 一:向上…...

阿一网络安全实战演练之利用 REST URL 中的服务器端参数污染
所需知识 要解决这个实验室问题,您需要了解以下内容: 如何确定用户输入是否包含在服务器端的 URL 路径或查询字符串中。如何使用路径遍历序列尝试更改服务器端请求。如何查找 API 文档。 这些内容在我们的 API 测试学院主题中有涵盖。 进入实验室 研…...

[游戏开发] LuaTable转string存读二进制文件
UE5和Unity通用此方案,只不过读写文件的接口略有不同,lua代码的处理是相同的。 下面两个方法是 LuaTable和字符串互相转换的代码 function XUtils.luaTableToString(tab, sp)sp sp or ""local s ""for k,v in pairs(tab) doif t…...
光伏业务管理系统的一些妙用功能
现在信息化流程化基本上每个行业都必须要有的了,光伏业务管理系统软件是一种专门用于光伏产业运营和管理的综合性系统,它结合了信息技术、数据分析、项目管理、客户管理等多个领域的知识,为光伏企业提供了一个全面、高效、智能的管理平台&…...

Java面试八股之请简述消息队列的发布订阅模式
请简述消息队列的发布订阅模式 发布订阅(Publish-Subscribe,简称 Pub/Sub)模型是一种消息传递模式,它在组件之间提供了高度的解耦和灵活性。这种模式广泛应用于分布式系统、事件驱动架构以及消息队列系统中。下面是发布订阅模型的…...

七、2 ADC数模转换器有关函数介绍(Keil5)
函数介绍 (1)ADCCLK的配置函数(在rcc.h中) (2)ADC的库函数(在adc.h中)...
了解载波侦听多路访问CSMA(上)
1.CSMA的思想 CSMA的全称是Carrier Sense Multiple Access,在笔者的理解中,其更趋向于一种理论研究的随机接入协议,或者说,基于其思想诞生了比如CSMA/CD与CSMA/CA这样的具体协议。CSMA可以分成以下三种: 1-persistent…...

开启教育新征程:“集师” 知识付费平台搭建
在教育培训行业竞争日益激烈的今天,如何脱颖而出,实现知识的最大价值?答案就在 “集师” 知识付费平台搭建! “集师” 为您打造专属的知识付费平台,提供一站式解决方案。无论您是专注于学科教育、艺术培训还是职业技能…...
Vue3 + Electron 创建新的子窗口 且子窗口唯一
main.js const { app, BrowserWindow, ipcMain } require(electron) ...ipcMain.on(window-create, () > {createChildWindow() })let childWindow nullconst createChildWindow () > {// 如果窗口存在 先销毁if (childWindow) {childWindow.destroy()childWindow n…...

海康VisionMaster使用学习笔记2-相机取图及参数设置
相机取图及参数设置 1. 关联相机-相机管理界面 除了以上两类外,第三方相机都可以通过全局相机进行连接 2. 相机参数设置 相机连接 跨网段IP,枚举 图像缓存数量 实时取流,断线重连 只有支持组播的相机才可以实时取流 触发设置 触发源 LINE0 可以保护电路 LINE2 可配置输入输出…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...