一、什么是验证码?
1.验证码就是我们平日里登录网站时所看到的随机字符,它是一种用于区分人机或者用户的简单程序,平常输入一些重要信息或登陆注册的时候需要使用验证码。
2.验证码的最大作用就是用于区分人机与用户以防止恶意程序非法访问攻击。
二、生成验证码
生成验证码的步骤通常是先创建图片源、画布、画笔,然后通过画笔在画布上绘画最后再将画布写入通过图片源获取的图片中。
1.创建图片源
ImageIcon icon=new ImageIcon(request.getServletContext().getRealPath("/images/验证.png"));
通过ImageIcon这个类获取图片源,参数使用request.getServletContext().getRealPath()获取到服务器的真实路径再获取图片路径最后成功创建图片源。(图片要使用png格式不然最后可能无效)
2.创建画布
BufferedImage buff=new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
BufferedImage是image的实现类,主要作用是将一幅图片加载到内存中。使用BufferedImage创建画布,其参数传入ImageIcon的宽高和BufferedImage的图像像素类型,本文使用的是TYPE_4BYTE_ABGR,它表示包含 8 位 ABGR 像素的图像,其中每个像素由 32 位整数表示。
3.创建画笔
Graphics gr=buff.getGraphics();
通过Graphics创建画笔,其对象通过BufferedImage返回的Graphics对象获得。
4.绘画干扰线
验证码需要干扰线来加大机器识别的难度,而用户则不会受到干扰线的阻挠。
(1).绘画划线
for(int i=0;i<10;i++)
{
gr.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
int a=r.nextInt(80);
int b=r.nextInt(35);
int a1=r.nextInt(80);
int b1=r.nextInt(35);
gr.drawLine(a,b,a1,b1);
}
验证码的生成离不开随机数,我们需要随机数来制作随机的验证码,r是我创建的随机数对象。此代码可以生成十条不同的长度,位置,角度,颜色的横线。我们通过Graphics.的drawLine方法绘画划线,而setColor则是设置本次循环划线的颜色。
(2).绘画干扰点
for(int i=0;i<40;i++)
{
gr.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
int a=r.nextInt(80);
int b=r.nextInt(35);
gr.drawOval(a,b,1,2);
}
绘画干扰点与干扰线差不多,只需要将drawLine替换成drawOval即可。绘画干扰点的时候要注意drawOval其实是绘制一个圆,而它不能像线一样随机大小,只能设置成特定大小,如果它太大会将验证码遮住导致用户也看不见了。
5.创建随机字符串
验证码最核心的内容就是其中的几个字符,我们需要创建随机的字符实现验证码的核心内容。
(1).设置需要的所有字符
String[] ar= {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","U","V","X","Y","Z","q","w","e","r","t","y","u","i","o","p",
"1","2","3","4","5","6","7","8","9"};
创建所需要随机到的字符储存在一个数组内,之后使用随机数提取字符拼装。
(2).设置需要的字体类型
String[] ag= {"宋体","微软幼圆","楷书","黑体","微软雅黑","仿宋"};
将需要使用的字体类型储存在数组内方便之后使用。
(3).创建随机的验证码字符
for(int i=0;i<4;i++)
{
gr.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255)));
gr.setFont(new Font(ag[r.nextInt(4)], Font.BOLD, r.nextInt(10)+15));
String a=ar[r.nextInt(43)];
gr.drawString(a,r.nextInt(10)+20*i,r.nextInt(10)+20);
}
这里我使用for循环创建了4个随机的字符。我使用setColor设置随机字符的颜色,setFont设置字体的类型和大小(Font.BoLD是设置字体变粗)。将之前存的字符数组通过随机数取其中一个装入变量,drawString是绘画字符并设置其位置(例如随机到左上、左下、右上等等)设置的随机数限制是避免字符位置偏移过多导致偏移出图片外或者占用其他字符的位置.
6.将编辑好的验证码存入图片中
ImageIO.write(buff, "png",response.getOutputStream());
使用ImageIo.write将图片存入返回给客户端的响应流中。
第一个参数用画布对象,指存入此画布的图片。
第二个参数使用图片格式后缀。
第三个参数使用response.getOutputStream(),指定ImageIo.write将图片存入的位置设置为客户端响应流。
response是在Controller层通过方法参数获得的.
三、在前端页面使用验证码
1.显示验证码
<img id="img" onclick="myke()" style="cursor:pointer;float: right" src="userinfo/Code"/>
在后端生成验证码后直接通过路径访问生成验证码的方法就能获取到验证码图片。
2.点击验证码后更换
function myke()
{
document.getElementById("img").src="userinfo/Code?t="+Math.random();
}
通过点击事件触发myke()方法,然后触发所有img验证码生成的访问路径就能实现替换验证码.
本文作者是个小白此文章只是笔记作用有错误可以请大佬们支出错误