1.为什么要有验证码功能?
大家在访问某个网站的登陆界面的时候,除了要输入用户名和密码,还要求输入验证码,有些容易识别的验证码还好说,那些躲在干扰线后面让人难以识别的验证码着实让人恼火。为什么非要输入验证码呢?原来这也是为了我们的账户安全考虑,试想一下,如果不需要输入验证码,那我们便可以写一个程序,枚举所有可能的字符,来暴力破解我们的密码,当CPU的运行效率非常快的时候,我们的密码就会很容易被破解,但是引入了验证码之后,因为每次输入密码时还要输入验证码,便使暴力破解成为了不可能
2.那怎样实现验证码功能呢?
下面看代码
package edu.swpu.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int width = 110;
int height = 25;
//在内存中创建一个图像对象
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//创建一个画笔
Graphics g = img.getGraphics();
//给图片添加背景色
g.setColor(Color.PINK);//设置一个颜色
g.fillRect(1, 1, width-2, height-2); //填充颜色
//给边框一个色
g.setColor(Color.RED);
g.drawRect(0, 0, width-1, height-1); //设置边框的显示坐标
//设置文本样式
g.setColor(Color.BLUE);
g.setFont(new Font("宋体", Font.BOLD|Font.ITALIC, 15));
//给图片添加文本
Random rand = new Random();
int position = 20;
for (int i = 0; i < 4; i++) {
g.drawString(rand.nextInt(10)+"", position, 20); //给图片填充文本
position += 20;
}
//添加9条干扰线
for (int i = 0; i < 9; i++) {
g.drawLine(rand.nextInt(width), rand.nextInt(height),
rand.nextInt(width), rand.nextInt(height));
}
//将图片对象以流的方式输出的客户端
ImageIO.write(img, "jpg", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
上面的代码实现起来也的确太复杂了,我们可以借助工具包ValidateCode.jar
来简化实现步骤,代码如下
package edu.swpu.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dsna.util.images.ValidateCode;
public class ServletDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ValidateCode vc = new ValidateCode(110, 25, 4, 9);
String code = vc.getCode(); //得到生成的字符
vc.write(response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
这时我们刷新界面的时候,验证码还是刚才生成的,可能是客户端使用了缓存,我们需要告诉客户不不进行缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setIntHeader("expires", 0);