前提
图片验证码的工具是两个版本 简单的图片验证码是网上翻来的
业务逻辑很简单,生成一个图片验证码,保存到Session里,然后将图片输入注入Response对象 传递给前端,显示出来
前端用户把验证码图片中的数字提交到后端
后端从Session把验证码拿到 跟用户输入的作比对 如此就完成了验证码的逻辑
复杂版的是纯原创,基于Redis的缓存功能 将工具生成的图片正码数字保存到Redis,同时利用MyBatisPlus提供的雪花算法生成一个Redis的Key值,将key值和验证码图片一起发送给前端,前端再用户输入验证码后,将验证码和对应的Key值一起传回后端
后端通过Key值去Redis拿到验证码的号码,于用户输入的数据做比对 如此也能完成验证码的逻辑
这里有两个小细节
Session模式是直出图片给前端 从前端角度来讲 接收到的就是一个普通图片的 直接显示就完事儿了
Redis模式是返回一个Json数据 里边包含了Base64之后的图片数据 需要前端进行一定的处理才能显示
另外
Redis版本的图片 还用到了JPEGEncode的图片压缩 貌似这种尺度的压缩不是很明显 这个后续再研究
Session版 简单高效
- Util 工具类
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/***
* Author: YL.Lou
* Class: RandomValidateCodeUtil
* Project: base
* Introduce:
* DateTime: 2022-06-30 13:59
***/
@Slf4j
@Component
public class VerifyCodeImageUtil {
@Autowired
private Result result;
public static final String RANDOM_CODE_KEY= "RANDOM_VALIDATE_CODE_KEY";//放到session中的key
private int width = 95;// 图片宽
private int height = 25;// 图片高
private int stringCount = 4;// 随机产生字符数量
private int fontSize = 18; // 字符大小
private Random random = new Random();
/**
* 获得字体 HANGING_BASELINE CENTER_BASELINE PLAIN
*/
private Font getFont() {
return new Font("Fixedsys", Font.BOLD, fontSize);
}
/**
* 获得颜色
*/
private Color getRandColor(int fc, int bc) {
int r = BaseUtil.getRandomNum(fc,bc);
int g = BaseUtil.getRandomNum(fc,bc);
int b = BaseUtil.getRandomNum(fc,bc);
return new Color(r, g, b);
}
/**
* 生成随机图片
*/
public void getRandCode(
Integer w,
Integer h,
Integer l,
Integer s,
HttpServletRequest request,
HttpServletResponse response
) {
HttpSession session = request.getSession();
if (null != w) this.width = w;
if (null != h) this.height = h;
if (null != l) this.stringCount = l;
if (null != s) this.fontSize = s;
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0, 0, width, height);//图片大小
// 绘制背景干扰线
for (int i = 0; i <= 10; i++) {
drawLine(g);
}
// 绘制随机字符
String randomString = BaseUtil.getRandom(stringCount);
for (int i = 0; i < stringCount; i++) {
drawString(g, randomString, i);
}
// 绘制前景干扰线
for (int i = 0; i <= 5; i++) {
drawLine(g);
}
//将生成的随机字符串保存到session中
session.removeAttribute(RANDOM_CODE_KEY);
session.setAttribute(RANDOM_CODE_KEY, randomString);
// 释放资源
g.dispose();
try {