一、验证码简介
一次性验证码的主要目的就是为了限制人们利用工具软件来暴力猜测密码。
服务器程序接收到表单数据后,首先判断用户是否填写了正确的验证码,只有该验证码与服务器保存的验证码匹配的时候,服务器程序才能正常的处理表单。
密码猜测工具要逐一尝试每个密码的前提条件是先输入正确的验证码,而验证码是一次性有效的,这样基本上就阻断了密码猜测工具的自动处理过程。
二、验证码的实现
package cn.session; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.p_w_picpath.BufferedImage; import java.io.IOException; import java.util.Random; import javax.p_w_picpathio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /*验证码*/ @SuppressWarnings("serial") public class CheckCode extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 120; int height = 30; //在内存中生成图片 BufferedImage p_w_picpath = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //先获取画笔 Graphics2D g = (Graphics2D) p_w_picpath.getGraphics(); //设置画笔的颜色为灰色 g.setColor(Color.gray); //画填充的矩形 g.fillRect(0, 0, width, height); //设置画笔的颜色为蓝色,画边框 g.setColor(Color.BLUE); g.drawRect(0, 0, width-1, height-1); //下面是画随机数 //准备好数据,随意获取4个字符 String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; //设置画笔的颜色为×××,设置字体 g.setColor(Color.YELLOW); g.setFont(new Font("微软雅黑,隶书", Font.BOLD, 20)); StringBuffer sb = new StringBuffer(); Random random = new Random(); int x = 20;//设置验证码中字的左边距 int y = 20;//设置验证码中字的上边距 for (int i = 0; i < 4; i++) { //void rotate(double theta,double x,double y) //theta 弧度 //hudu = jiaodu * Math.PI /180; //jiaodu在正负30之间 int jiaodu = random.nextInt(60) - 30; double hudu = jiaodu * Math.PI / 180; g.rotate(hudu, x, y); //获取下标 int index = random.nextInt(words.length()); //返回指定下标位置的字符串,随机获取字符 char ch = words.charAt(index); //把字符拼凑成起来,以便用于存放入session中 sb.append(ch); //画验证码中的内容即4个随机数 g.drawString(""+ch, x, y); //将弧度归位 g.rotate(-hudu, x, y); x+= 20;//设置验证码中的字符之间的距离是20 } //将验证码中的字符放入到session中 request.getSession().setAttribute("code", sb.toString()); //设置画笔颜色 g.setColor(Color.GREEN); int x1,x2,y1,y2; //画干扰线 //两点确定一条直线 //而且干扰线的坐标(x1,y1)(x2,y2)不能超过验证码的宽和高 for (int i = 0; i < 4; i++) { x1 = random.nextInt(width); y1 = random.nextInt(height); x2 = random.nextInt(width); y2 = random.nextInt(height); g.drawLine(x1, y1, x2, y2); } //将验证码输出到客户端 ImageIO.write(p_w_picpath, "jpg", response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
三、验证码封装到jsp页面
<%@page import="javax.p_w_picpathio.ImageIO"%> <%@page import="java.awt.Font"%> <%@page import="java.awt.Color"%> <%@page import="java.awt.Graphics2D"%> <%@page import="java.awt.p_w_picpath.BufferedImage"%> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>"> My JSP 'identifyingCde;.jsp' starting page <% int width = 120; int height = 30; //在内存中生成图片 BufferedImage p_w_picpath = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //先获取画笔 Graphics2D g = (Graphics2D) p_w_picpath.getGraphics(); //设置画笔的颜色为灰色 g.setColor(Color.gray); //画填充的矩形 g.fillRect(0, 0, width, height); //设置画笔的颜色为蓝色,画边框 g.setColor(Color.BLUE); g.drawRect(0, 0, width-1, height-1); //下面是画随机数 //准备好数据,随意获取4个字符 String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; //设置画笔的颜色为×××,设置字体 g.setColor(Color.YELLOW); g.setFont(new Font("微软雅黑,隶书", Font.BOLD, 20)); StringBuffer sb = new StringBuffer(); Random random = new Random(); int x = 20;//设置验证码中字的左边距 int y = 20;//设置验证码中字的上边距 for (int i = 0; i < 4; i++) { //void rotate(double theta,double x,double y) //theta 弧度 //hudu = jiaodu * Math.PI /180; //jiaodu在正负30之间 int jiaodu = random.nextInt(60) - 30; double hudu = jiaodu * Math.PI / 180; g.rotate(hudu, x, y); //获取下标 int index = random.nextInt(words.length()); //返回指定下标位置的字符串,随机获取字符 char ch = words.charAt(index); //把字符拼凑成起来,以便用于存放入session中 sb.append(ch); //画验证码中的内容即4个随机数 g.drawString(""+ch, x, y); //将弧度归位 g.rotate(-hudu, x, y); x+= 20;//设置验证码中的字符之间的距离是20 } //将验证码中的字符放入到session中 request.getSession().setAttribute("code", sb.toString()); //设置画笔颜色 g.setColor(Color.GREEN); int x1,x2,y1,y2; //画干扰线 //两点确定一条直线 //而且干扰线的坐标(x1,y1)(x2,y2)不能超过验证码的宽和高 for (int i = 0; i < 4; i++) { x1 = random.nextInt(width); y1 = random.nextInt(height); x2 = random.nextInt(width); y2 = random.nextInt(height); g.drawLine(x1, y1, x2, y2); } //将验证码输出到客户端 ImageIO.write(p_w_picpath, "jpg",response.getOutputStream()); out.clear(); out = pageContext.pushBody(); %>