图片验证码实现的几种方式
一、Google Kaptcha
1、简介
kaptcha 是一个非常实用的验证码生成工具。有了它,你可以生成各种样式的验证码,因为它是可配置的。kaptcha工作的原理是调用 com.google.code.kaptcha.servlet.KaptchaServlet,生成一个图片。同时将生成的验证码字符串放到 HttpSession中。
使用kaptcha可以方便的配置:
- 验证码的字体
- 验证码字体的大小
- 验证码字体的字体颜色
- 验证码内容的范围(数字,字母,中文汉字!)
- 验证码图片的大小,边框,边框粗细,边框颜色
- 验证码的干扰线(可以自己继承com.google.code.kaptcha.NoiseProducer写一个自定义的干扰线)
- 验证码的样式(鱼眼样式、3D、普通模糊……当然也可以继承com.google.code.kaptcha.GimpyEngine自定义样式)
2、maven依赖
<dependency><groupId>pro.fessional</groupId><artifactId>kaptcha</artifactId><version>2.3.3</version>
</dependency>
<dependency><groupId>com.jhlabs</groupId><artifactId>filters</artifactId><version>2.0.235</version>
</dependency>
3、验证码配置类
import java.util.Properties;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;@Component
public class KaptchaConfig {@Beanpublic DefaultKaptcha getDefaultKaptcha() {DefaultKaptcha defaultKaptcha = new DefaultKaptcha();Properties properties = new Properties();// 图片边框properties.setProperty("kaptcha.border", "no");// 边框颜色properties.setProperty("kaptcha.border.color", "black");//边框厚度properties.setProperty("kaptcha.border.thickness", "1");// 图片宽properties.setProperty("kaptcha.image.width", "200");// 图片高properties.setProperty("kaptcha.image.height", "50");//图片实现类properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");//文本实现类properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");//文本集合,验证码值从此集合中获取properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");//验证码长度properties.setProperty("kaptcha.textproducer.char.length", "4");//字体properties.setProperty("kaptcha.textproducer.font.names", "宋体");//字体颜色properties.setProperty("kaptcha.textproducer.font.color", "black");//文字间隔properties.setProperty("kaptcha.textproducer.char.space", "5");//干扰实现类properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");//干扰颜色properties.setProperty("kaptcha.noise.color", "blue");//干扰图片样式properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");//背景实现类properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");//背景颜色渐变,结束颜色properties.setProperty("kaptcha.background.clear.to", "white");//文字渲染器properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");Config config = new Config(properties);defaultKaptcha.setConfig(config);return defaultKaptcha;}}
4、接口返回图片验证码
在获取验证码的类中直接引入配置类即可
/*** 验证码类:Google Kaptcha*/ @Autowired DefaultKaptcha defaultKaptcha;
/*** 获取图片验证码** @return* @throws Exception*/public RspObjectBO<VerifyCodeRspBO> verifyCodeGet(VerifyCodeReqBO reqBO) throws Exception {RspObjectBO<VerifyCodeRspBO> res = new RspObjectBO<>();VerifyCodeRspBO data = new VerifyCodeRspBO();String verifyId = CommonUtils.getUUID();String createText = defaultKaptcha.createText();log.info("验证码内容:{}", createText);BufferedImage bi = defaultKaptcha.createImage(createText);ByteArrayOutputStream stream = new ByteArrayOutputStream();ImageIO.write(bi, "jpeg", stream);String verifyCode = Base64.encode(stream.toByteArray());stream.flush();stream.close();RBucket<String> rBucket = redissonClient.getBucket(RedisKeyConstants.VerifyCodeKey + verifyId, StringCodec.INSTANCE);if (Objects.nonNull(reqBO.getDev_type()) && reqBO.getDev_type().equals(DeviceTypeEnum.Terminal_WX_Xcx.getType())) {rBucket = redissonClient.getBucket(RedisKeyConstants.VerifyCodeKey + reqBO.getDev_type() + verifyId, StringCodec.INSTANCE);}rBucket.set(createText, 3, TimeUnit.MINUTES);data.setVerifyid(verifyId);data.setVerifydata(verifyCode);res.setData(data);return res;}
二、自定义实现
import cn.hutool.core.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;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.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;public class RandomValidateCodeUtil {private static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";//放到session中的keyprivate static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class);// private String randString = "0123456789";//随机产生只有数字的字符串 private String//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串private int width = 95;// 图片宽private int height = 30;// 图片高private int lineSize = 40;// 干扰线数量private int stringNum = 4;// 随机产生字符数量private Random random = new SecureRandom();/*** 获得字体*/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);}/*** 生成随机图片 存储到session中*/public void getRandomCode(HttpServletRequest request, HttpServletResponse response) {HttpSession session = request.getSession();// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作Graphics g = image.getGraphics();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);g.dispose();try {// 将内存中的图片通过流动形式输出到客户端ImageIO.write(image, "JPEG", response.getOutputStream());} catch (Exception e) {logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);}}/*** 生成随机图片验证码*/private String getRandomCode() throws IOException {// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作Graphics g = image.getGraphics();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);}g.dispose();//返回base64图片ByteArrayOutputStream stream = new ByteArrayOutputStream();ImageIO.write(image, "jpeg", stream);String verifiCode = Base64.encode(stream.toByteArray());stream.flush();stream.close();return verifiCode;}/*** 绘制字符串*/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(randString.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);}/*** 获取随机的字符*/private String getRandomString(int num) {return String.valueOf(randString.charAt(num));}public static void main(String[] args) throws IOException {RandomValidateCodeUtil randomValidateCodeUtil = new RandomValidateCodeUtil();System.out.println(randomValidateCodeUtil.getRandomCode());}
}
@RequestMapping("getVerifiCode")@ResponseBodypublic void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {/*1.生成验证码2.把验证码上的文本存在session中3.把验证码图片发送给客户端*/ImageVerificationCode ivc = new ImageVerificationCode(); //用我们的验证码类,生成验证码类对象BufferedImage image = ivc.getImage(); //获取验证码request.getSession().setAttribute("text", ivc.getText()); //将验证码的文本存在session中ivc.output(image, response.getOutputStream());//将验证码图片响应给客户端}
三、Hutool工具类实现
1、Hutool工具简介
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
2、引入maven依赖
<dependency><groupId>com.xiaoleilu</groupId><artifactId>hutool-all</artifactId><version>3.2.3</version>
</dependency>
3、验证码功能介绍
验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:
●createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
●getCode 获取验证码的文字内容
●verify 验证验证码是否正确,建议忽略大小写
●write 将验证码写出到目标流中
其中write方法只有一个OutputStream,ICaptcha实现类可以根据这个方法封装写出到文件等方法。AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。
LineCaptcha线段干扰的验证码
//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);//图形验证码写出,可以写出到文件,也可以写出到流
lineCaptcha.write("d:/line.png");
//输出code
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");//重新生成验证码
lineCaptcha.createCode();
lineCaptcha.write("d:/line.png");
//新的验证码
Console.log(lineCaptcha.getCode());
//验证图形验证码的有效性,返回boolean值
lineCaptcha.verify("1234");
CircleCaptcha圆圈干扰验证码
//定义图形验证码的长、宽、验证码字符数、干扰元素个数CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);//图形验证码写出,可以写出到文件,也可以写出到流captcha.write("d:/circle.png");//验证图形验证码的有效性,返回boolean值captcha.verify("1234");
ShearCaptcha扭曲干扰验证码
//定义图形验证码的长、宽、验证码字符数、干扰线宽度ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);//ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4);//图形验证码写出,可以写出到文件,也可以写出到流captcha.write("d:/shear.png");//验证图形验证码的有效性,返回boolean值captcha.verify("1234");
自定义验证码
有时候标准的验证码不满足要求,比如我们希望使用纯字母的验证码、纯数字的验证码、加减乘除的验证码,此时我们就要自定义CodeGenerator
// 自定义纯数字的验证码(随机4位数字,可重复)
RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
lineCaptcha.setGenerator(randomGenerator);
// 重新生成code
lineCaptcha.createCode();
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
// 自定义验证码内容为四则运算方式
captcha.setGenerator(new MathGenerator());
// 重新生成code
captcha.createCode();
图片验证码实现的几种方式相关推荐
- 前端实现图片快速反转替换_canvas实现图片镜像翻转的2种方式
这篇文章我们来讲一下在网站建设中,canvas实现图片镜像翻转的2种方式.本文对大家进行网站开发设计工作或者学习都有一定帮助,下面让我们进入正文. 1. 通过canvas自带的画布方法进行翻转 var ...
- 全网最全!!Qt实现图片旋转及图片旋转动画的几种方式
实现图片旋转的两种方式 第一种方案 使用 QPixmap 的 transformed 函数来实现旋转,这个函数默认是以图片中心为旋转点,不能设置旋转的中心点,使用如下: QMatrix matrix; ...
- 元素导出为图片与pdf的几种方式
文章目录 原生方法将canvas元素导出为图片 使用库将html元素导出为图片: 使用库将html元素导出为pdf 原生方法将canvas元素导出为图片 使用原生javascript的方法将canva ...
- vue获取上传图片的名字和路径_使用Vue实现图片上传的三种方式
项目中需要上传图片可谓是经常遇到的需求,本文将介绍 3 种不同的图片上传方式,在这总结分享一下,有什么建议或者意见,请大家踊跃提出来. 没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务 ...
- Android 实现图片的高斯模糊(两种方式)
做项目时遇到要做图片模糊的需求,和微信语音通话的背景效果一样.网上有很多不错的博客,记录一下使用的两种方式. 1. 先来看看第一种,博客原文 首先创建一个工具类 /*** 快速模糊化工具*/ publ ...
- 实现图片染色效果的三种方式
为一张彩色图片增加染色效果变成灰度图片或者为灰度模式的图片增加染色效果变成彩色图片的css实现方式,有基于滤镜,基于混合模式的实现方式. 基于滤镜的实现方式 我们来为彩色图片添加一个灰色的染色效果,可 ...
- Android图片上传的两种方式
图片上传,以及带参数的图片上传是Android开发中,很常见的需求.但也是接口联调难度相对比较大的技术实现,本文介绍两种可靠的图片上传方式.一是通过 MultipartBody 来实现:二是通过图片转 ...
- css实现图片自适应容器的几种方式
css实现图片自适应容器 经常有这样一个场景,需要让图片自适应容器的大小. 1.img标签的方式 我们马上就能想到,把width.height 设置为100%啊.来看一哈效果. <div cla ...
- Nginx部署静态页面及引用图片有效访问的两种方式
nginx安装百度一下有很多,直接正题: 静态文件目录结构 file#文件位置 /home/service/file/ css js images html fonts 配置nginx.conf核心代 ...
- android 图片编辑 画圈,Android种图片圆形化的三种方式
最近被问到如何将图片转为圆形显示出来,当时脑袋一蒙,想着图片加载框架(如glide等)不都有这个功能了么?但感觉自己确实没有特别关注这方面的内容,就去学习整理了一波,不说了,直接上代码: import ...
最新文章
- php url重写配置,浅谈ThinkPHP的URL重写
- java多线程 ThreadPoolExecutor 策略的坑
- 计算机中,文本文件和二进制文件的区别
- Java怎么使用spring定时器_浅析spring定时器的使用
- 入门RabbitMQ核心概念
- 安装-apache skywalking (java 应用性能监控)
- 好玩的WPF第一弹:窗体抖动+边框阴影效果+倒计时显示文字
- CONTINUAL LEARNING FOR AUTOMATED AUDIO CAPTIONING USING THE LEARNING WITHOUT FORGETTING APPROACH
- catia飞机建模+flightgear飞行仿真
- 魔兽世界服务端linux,LightsHope/vMangos – 基于Ubuntu服务器的WOW私服搭建教程
- PID参数自整定库之一:继电反馈整定算法
- java软件工程师简历格式模板,重要概念一网打尽!
- github修改语言设置
- 【mongoDB】一一一一安装报错1058解决方案
- 电脑便签小工具分享 居然可以这般贴心好用
- python Matplotlib中时间刻度标签的设置/主副刻度
- 存储器管理中的局部性原理
- 最具有催眠功能的网站
- 记一次投票系统维护以及防止刷票springboot+redis
- 电动汽车 simulink仿真模型, 可进行整车动力性仿真测试(最高车速,最大爬坡,加入时间)和NEDC工况能耗测试