思路:
1.随机生成4个0-9内数字,放入session中。
2.将数字生产成图片,生产过程如下代码
3.将输入的验证码与session中的验证码匹配
生产图片的过程image.jsp
<pre name="code" class="plain"><%@ page contentType="image/jpeg"
import="java.awt.*,
java.awt.image.*,java.util.*,javax.imageio.*"
pageEncoding="utf-8"%>
<%!Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);//创建具有指定红色、绿色和蓝色值的不透明的 sRGB 颜色,这些值都在 (0 - 255) 的范围内
}%>
<%
out.clear();//清空缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);//禁止浏览器缓存
int width = 60, height = 20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//构造一个类型为预定义图像类型之一的 BufferedImage,TYPE_INT_RGB表示一个图像,它具有合成整数像素的 8 位 RGB 颜色分量。
Graphics g = image.getGraphics();//Graphics 类是所有图形上下文的抽象基类,允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
//getGraphics 创建供绘制闭屏图像(off-screen image)使用的图形上下文。
Random random = new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);// 填充指定的矩形。
g.setFont(new Font("Times New Roman", Font.ITALIC, 18));//Font(String name, int style, int size)
//根据指定名称、样式和磅值大小,创建一个新 Font。
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {// 填充干扰线
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);//在此图形上下文的坐标系中,使用当前颜色在点 (x1, y1) 和 (x2, y2) 之间画一条线
}
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));//随机生成十以内的数字
sRand += rand;
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
g.drawString(rand, 13 * i + 6, 16);//使用此图形上下文的当前字体和颜色绘制由指定 string 给定的文本。
}
// 将验证码存入SESSION
session.setAttribute("sRand", sRand);
g.dispose();//释放此图形的上下文以及它使用的所有系统资源。
ImageIO.write(image, "JPEG", response.getOutputStream());//使用支持给定格式的任意 ImageWriter 将一个图像写入
/* (1)getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
(2)getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
(3)Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
(4)Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象*/
%>