【SpringBoot】你不能不会的SpringBoot图形验证码生成
文章目录
- 手写验证码
- 新建验证码工具类
- Controller中调用
- Apifox中验证
- Hutool图形验证码
- 引入依赖
- LineCaptcha:线段干扰的验证码
- CircleCaptcha:圆形干扰验证码
- ShearCaptcha:扭曲干扰验证码
- GifCaptcha:GIF验证码
- 自定义验证码
- 纯数字验证码
- 纯字母验证码
- 四则运算验证码
这是一个登录页面,在登录的最后一部,很多时候都会让我们输入验证码,今天就来讲讲如何在SpringBoot中实现图形验证码的生成。验证码的生成是一个非常常用的工具类,网上有很多写法。
手写验证码
首先说明一下,这里的手写,并不是博主自己手写的,而是在GitHub中看到过一个项目,项目中有涉及到一个验证码的源码,感觉还不错。
新建验证码工具类
验证码工具类
public class Code {
public static final String RANDOMCODEKEY = "ValidateCode";
//将图片存放到Session中的key
private Random random = new Random();//生成随机数
private String randomString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//图片中随机产生的字母或数字
private int width = 80;//图片宽
private int height = 26;//图片高
private int lineSize = 40;//干扰线数量
private int stringNum = 4;//随机产生字符数量
//获得字体
private Font getFont(){
return new Font("Fixedsys",Font.CENTER_BASELINE,18);
}
//获得随机颜色值
private Color getRandColor(int fc,int bc){
if(fc > 255) {
fc = 255;
}
if(bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc-fc-16);
int g = fc + random.nextInt(bc-fc-14);
int b = fc + random.nextInt(bc-fc-18);
return new Color(r,g,b);
}
/*
* 返回随机的字符
*/
private String getRandomString(int num){
return String.valueOf(randomString.charAt(num));
}
/*
* 绘制字符串
*/
private String drawString(Graphics g, String randomString, int i){
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
String rand = String.valueOf(getRandomString(random.nextInt(this.randomString.length())));
randomString += rand;
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, 13 * i, 16);
return randomString;
}
/*
* 绘制干扰线
*/
private void drawLine(Graphics g){
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
g.drawLine(x, y, x + xl, y + yl);
}
//核心方法:生成随机验证码,并返回
public void getValidateCode(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,18));
g.setColor(getRandColor(110, 133));
//绘制干扰线
for(int i = 0;i <= lineSize; i++){
drawLine(g);
}
//绘制随机字符
String randomString = "";
for(int i = 1; i <= stringNum; i++){
randomString = drawString(g, randomString, i);
}
//将生成的随机字符串装进Session作用域
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
System.out.println(randomString);//输出生成的随机字符串
g.dispose();//关闭窗体,释放资源
try {
ImageIO.write(image, "JPEG", response.getOutputStream());//将内存中的图片通过流动形式输出到客户端
} catch (Exception e) {
e.printStackTrace();
}
}
}
在SpringBoot
项目中新建一个util
包,用于存放工具类,这样一个验证码工具类就写好了。
Controller中调用
工具类写好后,就可以在Controller
中调用
@GetMapping("/checkCode2")
public void checkcode2(HttpServletRequest request, HttpServletResponse response){
response.setContentType("image/jpeg");
response.setDateHeader("Expires",0);
response.setHeader("Pragma","no-cache");
response.setHeader("Cache-Control","no-cache");
//引用验证码工具类,生成验证码
Code code=new Code();
code.getValidateCode(request,response);
}
@GetMapping("/checkCode2")
: 这是一个Spring MVC注解,表示当客户端发送一个GET请求到/checkCode2路径时,将调用checkcode2方法。public void checkcode2(HttpServletRequest request, HttpServletResponse response)
: 这是一个控制器方法,接收HttpServletRequest和HttpServletResponse对象作为参数,用于处理HTTP请求和响应。response.setContentType("image/jpeg");
: 设置响应的内容类型为JPEG格式的图片。response.setDateHeader("Expires",0);
: 设置响应头Expires为0,表示页面内容已过期,浏览器应当每次都从服务器获取最新内容。response.setHeader("Pragma","no-cache");
: 设置响应头Pragma为no-cache,指示浏览器不要缓存页面内容。response.setHeader("Cache-Control","no-cache");
: 设置响应头Cache-Control为no-cache,进一步指示浏览器不要缓存页面内容。Code code=new Code();
: 创建一个Code类的实例。code.getValidateCode(request,response);
: 调用Code实例的getValidateCode方法,生成验证码并将其写入响应中。
Apifox中验证
Hutool图形验证码
Hutool官网:https://www.hutool.cn/docs/#/
正如官网简介所言,Hutool是一个小而全的Java工具类库,它提供了很多常用的工具类,几乎包罗万象。
今天我们使用的是hutool-captcha(图形验证码)。
引入依赖
这里使用的是Maven,如果是其他的项目构建工具,请参考文档。
单独引入图形验证码的依赖模块
<!-- 添加图形验证码依赖 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.8.6</version>
</dependency>
当然,为了方便,也可以按照文档中的方法,引入所有模块。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
LineCaptcha:线段干扰的验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//调用Hutool的图形验证码
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38, 5, 5);
定义图形验证码的长、宽、验证码字符数、干扰线宽度LineCaptcha captcha = CaptchaUtil.createLineCaptcha(130, 38)
定义图形验证码的长、宽
上面这两种写法都是可以的
CircleCaptcha:圆形干扰验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//调用Hutool的图形验证码
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38, 5, 20);
定义图形验证码的长、宽、验证码字符数、干扰⭕个数CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(130, 38);
定义图形验证码的长、宽
圆形干扰验证码同样两种写法。
ShearCaptcha:扭曲干扰验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//调用Hutool的图形验证码
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38,5,5);
定义图形验证码的长、宽、验证码字符数、干扰线宽度ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 38);
定义图形验证码的长、宽
GifCaptcha:GIF验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
//调用Hutool的图形验证码
GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38,5);
定义GIF验证码的长、宽、验证码字符数GifCaptcha captcha = CaptchaUtil.createGifCaptcha(130, 38);
定义GIF验证码的长、宽
大家可以去试试,这里截不出那种Gif的效果
自定义验证码
纯数字验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
// 自定义纯数字的验证码(随机4位数字,可重复)
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);
captcha.setGenerator(randomGenerator);
// 重新生成code
captcha.createCode();
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
当然除了LineCaptcha,CircleCaptcha,GifCaptcha,ShearCaptcha都是可以的
纯字母验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
// 自定义纯数字的验证码(随机4位数字,可重复)
RandomGenerator randomGenerator = new RandomGenerator("abcdefghijklmnopqrstuvwyzx", 4);
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100);
captcha.setGenerator(randomGenerator);
// 重新生成code
captcha.createCode();
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}
四则运算验证码
@GetMapping("/checkCode1")
public void checkCode(HttpServletResponse response) throws IOException {
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
// 自定义验证码内容为四则运算方式
captcha.setGenerator(new MathGenerator());
// 重新生成code
captcha.createCode();
//指示浏览器不要缓存页面内容
response.setHeader("Pragma","no-cache");
//进一步指示浏览器不要缓存页面内容
response.setHeader("Cache-Control","no-cache");
//表示页面内容已过期,浏览器应当每次都从服务器获取最新内容
response.setDateHeader("Expires",0);
//表示返回的内容为JPEG格式的图片
response.setContentType("image/jpeg");
//图片验证码写出
captcha.write(response.getOutputStream());
//关闭流
response.getOutputStream().close();
}