作者:传智播客Java培训学院
首发:http://www.itcast.cn/javaee
生成验证码图片
验证码是Completely Automated Public Turing test to tell Computers and Humans Apart(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序,可以防止:恶意破解密码、刷票、论坛灌水、有效防止某个黑客对某一特定注册用户,用特定程序暴力破解方式进行不断的登录尝试。实际上验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。
下面我们就来学习如何自动生成一个验证码图片,案例的源代码点击此处进行下载,具体如下:
大家想必在登录某个网站的时候都输入过验证码,如图1-1所示:
图1-1 验证码
下面通过一个案例来学习如何自动生成一个验证码图片:
(1)创建一个web应用,名称为Example1,在该应用下的src目录下新建一个Class类,名称为ImageTest,主要代码如例1-1所示:
例1-1 ImageTest.java
public class ImageTest { |
在例1-1中,首先要获得图片缓冲区,即BufferedImage类的一个对象,BufferedImage类的构造方法中,第一个参数和第二个参数表示图片的长和宽,第三个参数是图片的类型;然后获取绘制环境,也可以理解为获取当前图片的画笔,使用该对象可以设置一系列的属性,例如图片的背景颜色、填充形状等。最后使用ImageIO类的write()方法将当前画好的图片写到指定的输出流中。
(2)测试fun1()方法,去F盘查看生成的图片效果如何,如图1-2所示:
图1-2 绘制的图片
如图1-2所示,绘制的图片背景色是白色,字符串“Hello”的颜色是红色,该字符串的位置也是由我们自己设置的,可以调整。
通过以上对自动绘制图片的了解,下面我们来完成另外一个绘制图片的类,这个类相较于上面的ImageTest类要复杂很多,如下所示:
(1)在ImageTest同包下新建一个Class类,名称为VerifyCode,下面我们对类中的方法进行一一介绍。首先来看该类的成员变量,如例1-2所示:
例1-2 VerifyCode.java类中的成员变量
public class VerifyCode { |
例1-2中,成员变量w、h分别表示图片的长和宽;成员变量r是Random类型的对象,用来生成随机数;成员变量fontNames是列举验证图片中验证码的字体类型;成员变量codes是列举验证码的所有的可选字符;成员变量bgColor是验证图片的背景色;成员变量text是图片上的验证码。
(2)VerifyCode类的生成随机颜色的方法,主要代码如例1-3所示:
例1-3 randomColor()方法
// 生成随机的颜色 |
例1-3中,r是Random类型的对象,r.nextInt(int n)方法返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值n(不包括)之间均匀分布的 int值。其中局部变量red、green、blue分别代表颜色的RGB的红、绿、蓝三个通道的颜色值。该方法返回的是随机产生的颜色。
(3)VerifyCode类的生成随机字体的方法,主要代码如例1-4所示:
例1-4 randomFont()方法
// 生成随机的字体 |
例1-4中,r.nextInt(fontNames.length)方法是获得一个从0到成员变量fontNames数组的长度之间的整数index,然后将这个整数当作fontNames数组的下标,找到对应的字体类型。局部变量style是随机产生的样式,详情可参考例1-4中的代码注释,局部变量size是随机生成的字体大小,即字号,范围是从24~28;最后将该字体返回。
(4)VerifyCode类的生成随机的干扰线方法,主要代码如例1-5所示:
例1-5 drawLine()方法
// 画干扰线 |
例1-5中,局部变量num是记录干扰线的条数,然后创建当前图片的画笔Graphics2D类的对象,再利用r对象生成四个值,其中x1和x2的大小范围在0~70之间,y1和y2的大小在0~35之间,这四个值是用来作为确定一条直线的两个点的坐标,由于有三条干扰线,所以这里使用for循环,然后每循环一次就使用画笔对象g2的drawLine()方法绘制一条线。
(5)VerifyCode类的生成随机字符的方法,主要代码如例1-6所示:
// 随机生成一个字符 |
例1-6中,验证码的所有可选字符都在字符串codes中,通过r对象的nextInt()方法获得一个在0到codes.length范围内的整数index,然后调用charAt(index)方法获得指定索引的字符,并返回。
(6)VerifyCode类的创建BufferedImage的方法,主要代码如例1-7所示:
// 创建BufferedImage |
例1-7中,创建BufferedImage对象的步骤与例1-1相同,最后将创建的对象返回。
(7)VerifyCode类的获得验证码图片上的文本方法,主要代码如例1-8所示:
// 返回验证码图片上的文本 |
例1-8中的text是成员变量,代表图片上的验证码。该方法要在另一个方法getImage()调用之后调用,getImage()方法后面会详解。
(8)VerifyCode类的将图片保存到指定的输出流,主要代码如例1-9所示:
// 保存图片到指定的输出流 |
例1-9中,output()方法有两个参数,第一个参数是绘制的图片,第二个参数是图片将要保存的输出流;使用ImageIO类的write()方法将image对象以JPEG的格式保存在out输出流中。
(9)VerifyCode类的得到验证码图片的方法,主要代码如例1-10所示:
// 调用这个方法得到验证码 |
例1-10中,先调用createImage()方法创建图片缓冲区,然后得到绘制环境,即当前图片的画笔;再创建一个用来保存验证码文本的StringBuilder对象,利用for循环及以上提到的方法向图片中画4个字符,然后将sb对象的值赋给成员变量text,这时调用例1-8中的getText()方法就可以获得验证码文本。最后添加干扰线,再返回image对象。
(10)以上就是VerifyCode类的所有方法,现在我们在ImageTest类中定义一个单元测试方法fun2(),该方法的主要内容如例1-11所示:
@Test |
(11)执行fun2()方法,控制台上打印结果如图1-3所示:
图1-3 验证码信息
(12)由图1-3可知,验证码文本信息为“pxTy”,现在去F盘中找到验证码.jpg,打开如图1-4所示:
图1-4 验证码
在以后的开发中,想获得验证码就可以把VerifyCode类当作一个帮助类,将它拷贝到自己的项目中然后调用相应的方法就可以获得验证码图片。