J2EE验证码图片生成与刷新方法详解:从创建BufferedImage到点击刷新

2016 年 04 月 29 日 12 时 02 分 01 秒进行了更新,作者是 justPassBy。
这篇文章主要介绍了 J2EE 生成验证码图片的相关方法,还介绍了如何生成验证码图片以及如何点击刷新验证码的方法。感兴趣的小伙伴们可以参考一下。
验证码图片生成步骤
创建BufferedImage对象。
获取 BufferedImage 的画笔,这意味着调用 getGraphics()方法来获取 Graphics 对象。
调用 Graphics 对象的方法,先使用 setColor()方法,接着使用 fillRect()方法,以此来设置图片的背景颜色。
调用 Graphics 对象的方法来设置图片干扰线,其中包括设置颜色的 setColor()方法和绘制线条的 drawLine()方法。
调用 BufferedImage 对象来设置图片的噪点,具体是通过调用其 setRGB()方法来实现。
调用 Graphics 对象的相关方法来设置图片验证码,包括使用 setColor()方法、setFont()方法以及 drawString()方法。
验证码图片的宽度和高度需根据网站风格确定,所以字体大小要依据图片的宽度和高度来确定,这其中用到了一些小小的技巧。
package util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
导入 Java 的.awt.image 包中的 BufferedImage 类。
导入 Java 的输入输出相关类。使用 `ByteArrayOutputStream` 类来处理字节数组输出流。
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class Verification {
2. 这个字符串的内容是 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"。
/**
生成一个图片,其宽度为 width,高度为 height,验证码是 code。
* @param width 图片的宽
* @param height 图片的高
* @param code 验证码字符串
* @return 返回图片验证码
*/
公共静态的 BufferedImage 获取图像(整数宽度,整数高度,字符串代码);
获取图像,传入宽度、高度、代码以及 20 作为参数,然后返回该图像
}
/**
生成一个图片,其宽度为 width,高度为 height,验证码为 code,且该图片中干扰线的条数为 lineCnt。
* @param width 图片的宽
* @param height 图片的高
* @param code 验证码字符串
干扰线的条数为 lineCnt,建议其为 10 条左右,能够根据结果进行适当调整。
* @return 返回图片验证码
*/
公共静态的 BufferedImage 获取图像(整数宽度,整数高度,字符串代码,整数行数);
创建一个图像,其宽度为指定的宽度,高度为指定的高度,编码为指定的编码,行数为指定的行数,缩放比例为 0.01 并返回该图像。
}
/**
* 生成一个宽为width, 高为height, 验证码为code的图片,图片中干扰线的条数为lineCnt
* 噪声比为noiseRate,即图片中噪音像素点的百分比
* @param width 图片的宽
* @param height 图片的高
* @param code 验证码字符串
* @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
参数 noiseRate 表示图片中噪音像素点在总像素中所占的百分比。
* @return 返回图片验证码
*/
获取一个宽度为指定宽度、高度为指定高度、编码为指定编码、行数为指定行数且噪声率为指定噪声率的 BufferedImage。该 BufferedImage 是通过特定的方式生成的,其宽度为 width,高度为 height,编码为 code,行数为 lineCnt,噪声率为 noiseRate。
创建一个图像,其宽度为指定的宽度,高度为指定的高度,编码为指定的编码,行数为指定的行数,噪声率为指定的噪声率,然后返回该图像。
}
/**
*
* 生成一个宽为width, 高为height, 验证码为code的图片,图片中干扰线的条数为lineCnt
* 噪声比为noiseRate,即图片中噪音像素点的百分比
* @param width 图片的宽
* @param height 图片的高
* @param code 验证码字符串
* @param lineCnt 干扰线的条数,建议为10条左右,可根据结果适当调整
* @param noiseRate 图片中噪音像素点占总像素的百分比
* @return 返回图片验证码
*/
该图像的噪声率为指定的 noiseRate 。
定义一个整型变量 fontWidth ,它等于宽度 width 乘以 0.8 后取整的值,再除以编码 code 的长度。
定义一个整型变量 fontHeight,将其赋值为高度 height 乘以 0.7 后的整数值。
为了在不同的 width 和 height 情况下都能够生成效果良好的验证码。
字体的大小是 fontWidth 和 fontHeight 之中比较小的那个。
定义一个整型变量 fontSize ,它的值是 fontWidth 和 fontHeight 中的较小值 。
//drawString时要用到
定义一个整型变量 paddingX,它的值是宽度 width 乘以 0.1 后的结果并转换为整型。
定义一个整型变量 paddingY ,其值为 height 减去 (height 减去 fontSize) 除以 2 的结果 。
//创建图像
创建了一个 BufferedImage 对象 buffimg,其宽度为 width,高度为 height,类型为 BufferedImage.TYPE_INT_RGB。
//获得画笔
获取到的 buffimg 可以获取到 Graphics 对象 g 。
//设置画笔的颜色
g 设定颜色,这个颜色是从 200 到 255 这个范围内随机获取的颜色;
//然后填充一个矩形,即设置背景色
g 用指定的坐标和尺寸绘制一个矩形,起始坐标为(0, 0),宽度为 width,高度为 height,即填充了一个从左上角(0, 0)开始,宽度为 width、高度为 height 的矩形区域。
// 设置干扰线
for (int i = 0; i < lineCnt; i++) {
//随机获取干扰线的起点和终点
int xs = (int)(Math.random() * width);
int ys = (int)(Math.random() * height);
int xe = (int)(Math.random() * width);
int ye = (int)(Math.random() * height);
g.setColor(getRandColor(1, 255));
g.drawLine(xs, ys, xe, ye);
}
// 添加噪点
int area = (int) (noiseRate * width * height);
for(int i=0; i 255)
L = 255;
if(R > 255)
R = 255;
if(L < 0)
L = 0;
if(R < 0)
R = 0;
int interval = R - L;
int r = L + (int)(Math.random() * interval);
int g = L + (int)(Math.random() * interval);
int b = L + (int)(Math.random() * interval);
return new Color(r, g, b);
}
/**
* 随机生成若干个由大小写字母和数字组成的字符串
* @param len 随机生成len个字符
* @return 返回随机生成的若干个由大小写字母和数字组成的字符串
*/
public static String getRandCode(int len){
String code = "";
for(int i=0; i
使用验证码图片
在 verificationCode.java 这个 servlet 里调用上述的类来生成验证码图片,接着把该图片返回给客户端。
在处理 HTTP 请求时,通过 doGet 方法来响应。此方法接收 HttpServletRequest 请求对象和 HttpServletResponse 响应对象作为参数。在该方法内部,可能会抛出 ServletException 和 IOException 异常。
获取到请求对象 request ,然后通过 request 获取到 HttpSession 对象 session 。
//随机生成字符串,并写入session
获取四位随机码的操作由 Verification 类的 getRandCode 方法完成,获取到的随机码赋值给了 String 类型的 code 变量。
设置 session 的“verification”属性为 code。
BufferedImage 图像 = util.Verification 获取图像(100, 30, 代码, 5);
response 被设置为 "image/png" 的内容类型。
response 有一个输出流 out,out 就是 response 的 getOutputStream()所返回的流。
out.write(util.Verification.获取字节数组(image));
out.flush();
out.close();
}
在 index.jsp 里设置验证码。当用户点击验证码时,会调用 js 代码去请求服务器以获取新的验证码。由于上面生成验证码的那个 servlet 会被浏览器缓存,所以在 js 代码中需要给该 servlet 提供一个随机的参数。如此一来,浏览器就会向服务器发送请求以获得新的验证码,而不是从缓存中读取。
<%@page import="util.Verification"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
首先在 checkVerification.java 这个 servlet 中进行判断。判断的内容是用户输入的验证码是否正确。为了方便用户,验证码通常设置为大小写不敏感。所以需要先将验证码转化为小写字母,然后再进行比对。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
获取请求对象 request ,然后通过 request 获取会话对象 session ,即 session = request.getSession() 。
从 session 中获取名为 "verification" 的属性,并将其转换为 String 类型,得到的结果赋值给 verification 变量。
从请求中获取名为“submitVerification”的参数,将其赋值给字符串 submitVerification 。
response 获取到的 Writer 是 out,out 是一个 PrintWriter 类型的对象。
如果 verification 不为空且 submitVerification 也不为空。
如果 verification 转换为小写后与 submitVerification 转换为小写后相等,则
out.println("yes!!!");
}
else{
out.println("no!!!");
}
}
else{
out.println("no!!!");
}
session 移除了名为“verification”的属性;这样做的目的是防止用户重复提交表单。
}
/**
查看 HttpServlet 中的 doPost 方法,该方法接收 HttpServletRequest 请求和 HttpServletResponse 响应作为参数。
*/
在 doPost 方法中,接收 HttpServletRequest 请求和 HttpServletResponse 响应。在该方法内部,可能会抛出 ServletException 和 IOException 异常。
请提供需要改写的句子呀,你只给了“// TODO Auto-generated method stub”,没有具体的内容呢。
doGet(request, response);
}
最后运行的效果图如下