要完成验证码效果,需要在jsp界面、Servlet(两个)还有一个用来生成图片的普通类配合工作,可以分为4步:
第一步:写一个用来生成验证码图片域的类,即VerifyCode类,可以放在工具包中,也可以放在领域层中。代码基本是死的,用的时候直接复制粘贴即可,不必深究,在下面
第二步:创建一个jsp页面。因为我们通常在注册的时候用验证码,所以这个jsp可以是register.jsp。在这个jsp中有关验证码的代码基本都是死的,主要在两部分,一部分当然在表单中,在表单中创建文本框等,最重要的"下一张"的超链接,此处用到一个_change()函数。另一部分则是写在<head></head>中的js代码了,其实就是超链接中的_change()函数。核心代码在下面
第三步:生成一个Servlet,名字是VerifyCodeServlet ,主要作用是保存图片域的文本到session域中,为校验验证码的Servlet验证做准备并且把图片响应给jsp页面。代码在下面
第四步:创建registerServle。在这个servlet中,我们接受注册表单提交的数据,校验验证码及用户名等其他信息。核心代码在下面
代码
VerifyCode类代码如下:
<span style="font-size:18px;">import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; public class VerifyCode { <span style="white-space:pre"> </span>private int w = 70; <span style="white-space:pre"> </span>private int h = 35; <span style="white-space:pre"> </span>private Random r = new Random(); <span style="white-space:pre"> </span>// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"} <span style="white-space:pre"> </span>private String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" }; <span style="white-space:pre"> </span>// 可选字符 <span style="white-space:pre"> </span>private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; <span style="white-space:pre"> </span>// 背景色 <span style="white-space:pre"> </span>private Color bgColor = new Color(255, 255, 255); <span style="white-space:pre"> </span>// 验证码上的文本 <span style="white-space:pre"> </span>private String text; <span style="white-space:pre"> </span>// 生成随机的颜色 <span style="white-space:pre"> </span>private Color randomColor() { <span style="white-space:pre"> </span>int red = r.nextInt(150); <span style="white-space:pre"> </span>int green = r.nextInt(150); <span style="white-space:pre"> </span>int blue = r.nextInt(150); <span style="white-space:pre"> </span>return new Color(red, green, blue); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 生成随机的字体 <span style="white-space:pre"> </span>private Font randomFont() { <span style="white-space:pre"> </span>int index = r.nextInt(fontNames.length); <span style="white-space:pre"> </span>String fontName = fontNames[index];// 生成随机的字体名称 <span style="white-space:pre"> </span>int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体) <span style="white-space:pre"> </span>int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28 <span style="white-space:pre"> </span>return new Font(fontName, style, size); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 画干扰线 <span style="white-space:pre"> </span>private void drawLine(BufferedImage image) { <span style="white-space:pre"> </span>int num = 3;// 一共画3条 <span style="white-space:pre"> </span>Graphics2D g2 = (Graphics2D) image.getGraphics(); <span style="white-space:pre"> </span>for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值 <span style="white-space:pre"> </span>int x1 = r.nextInt(w); <span style="white-space:pre"> </span>int y1 = r.nextInt(h); <span style="white-space:pre"> </span>int x2 = r.nextInt(w); <span style="white-space:pre"> </span>int y2 = r.nextInt(h); <span style="white-space:pre"> </span>g2.setStroke(new BasicStroke(1.5F)); <span style="white-space:pre"> </span>g2.setColor(Color.BLUE); // 干扰线是蓝色 <span style="white-space:pre"> </span>g2.drawLine(x1, y1, x2, y2);// 画线 <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 随机生成一个字符 <span style="white-space:pre"> </span>private char randomChar() { <span style="white-space:pre"> </span>int index = r.nextInt(codes.length()); <span style="white-space:pre"> </span>return codes.charAt(index); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 创建BufferedImage <span style="white-space:pre"> </span>private BufferedImage createImage() { <span style="white-space:pre"> </span>BufferedImage image = new BufferedImage(w, h, <span style="white-space:pre"> </span>BufferedImage.TYPE_INT_RGB); <span style="white-space:pre"> </span>Graphics2D g2 = (Graphics2D) image.getGraphics(); <span style="white-space:pre"> </span>g2.setColor(this.bgColor); <span style="white-space:pre"> </span>g2.fillRect(0, 0, w, h); <span style="white-space:pre"> </span>return image; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 调用这个方法得到验证码 <span style="white-space:pre"> </span>public BufferedImage getImage() { <span style="white-space:pre"> </span>BufferedImage image = createImage();// 创建图片缓冲区 <span style="white-space:pre"> </span>Graphics2D g2 = (Graphics2D) image.getGraphics();// 得到绘制环境 <span style="white-space:pre"> </span>StringBuilder sb = new StringBuilder();// 用来装载生成的验证码文本 <span style="white-space:pre"> </span>// 向图片中画4个字符 <span style="white-space:pre"> </span>for (int i = 0; i < 4; i++) {// 循环四次,每次生成一个字符 <span style="white-space:pre"> </span>String s = randomChar() + "";// 随机生成一个字母 <span style="white-space:pre"> </span>sb.append(s); // 把字母添加到sb中 <span style="white-space:pre"> </span>float x = i * 1.0F * w / 4; // 设置当前字符的x轴坐标 <span style="white-space:pre"> </span>g2.setFont(randomFont()); // 设置随机字体 <span style="white-space:pre"> </span>g2.setColor(randomColor()); // 设置随机颜色 <span style="white-space:pre"> </span>g2.drawString(s, x, h - 5); // 画图 <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>this.text = sb.toString(); // 把生成的字符串赋给了this.text <span style="white-space:pre"> </span>drawLine(image); // 添加干扰线 <span style="white-space:pre"> </span>return image; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 返回验证码图片上的文本 <span style="white-space:pre"> </span>public String getText() { <span style="white-space:pre"> </span>return text; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>// 保存图片到指定的输出流 <span style="white-space:pre"> </span>public static void output(BufferedImage image, OutputStream out) <span style="white-space:pre"> </span>throws IOException { <span style="white-space:pre"> </span>ImageIO.write(image, "JPEG", out); <span style="white-space:pre"> </span>} } </span>
register.jsp核心代码如下:
在表单里写如下代码:
<span style="font-size:18px;"><form action="<c:url value='/RegisterServlet'/>" method="post"> <span style="white-space: pre;"></span> userName:<input name="userName"><br/> <span style="white-space: pre;"></span> verifyCode:<input type="text" name="verifyCode" size="3" /> <span style="white-space: pre;"></span> <img id="img" src="<c:url value='/VerifyCodeServlet'/>" /> <span style="white-space: pre;"></span> <a<span style="white-space: pre;"> </span>href="javascript:_change()">Change another</a><br/> <span style="white-space: pre;"></span> <input type="submit" value="register"> </form><span style="white-space: pre;"> </span></span>
<span style="font-size:18px;"><script type="text/javascript"> <span style="white-space:pre"> </span>function _change() { <span style="white-space:pre"> </span>/* <span style="white-space:pre"> </span> 1. 得到img元素 <span style="white-space:pre"> </span> 2. 修改其src为/工程名/VerifyCodeServlet <span style="white-space:pre"> </span> */ <span style="white-space:pre"> </span>var imgEle = document.getElementById("img"); <span style="white-space:pre"> </span>imgEle.src = "<c:url value='/VerifyCodeServlet'/>?xxx=" <span style="white-space:pre"> </span>+ new Date().getTime(); <span style="white-space:pre"> </span>} </script></span>
VerifyCodeServlet 代码如下:
<span style="font-size:18px;">import java.awt.image.BufferedImage; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.verifyCode_self.utils.VerifyCode; public class VerifyCodeServlet extends HttpServlet { <span style="white-space:pre"> </span>private static final long serialVersionUID = 1L; <span style="white-space:pre"> </span>public void doGet(HttpServletRequest request, HttpServletResponse response) <span style="white-space:pre"> </span>throws ServletException, IOException { <span style="white-space:pre"> </span>VerifyCode vc = new VerifyCode(); <span style="white-space:pre"> </span>BufferedImage image = vc.getImage(); <span style="white-space:pre"> </span>String test = vc.getText(); <span style="white-space:pre"> </span>System.out.println("本次验证码是:" + test + "(不分大小写)");// 测试信息 <span style="white-space:pre"> </span>request.getSession().setAttribute("session_vcode", test);// 2.保存图片上的文本到session域中,为校验验证码的Servlet验证做准备 <span style="white-space:pre"> </span>VerifyCode.output(image, response.getOutputStream());// 3.把图片响应给jsp页面 <span style="white-space:pre"> </span>} }</span>
RegisterServlet 核心代码如下:
<span style="font-size:18px;">import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RegisterServlet extends HttpServlet { <span style="white-space:pre"> </span>private static final long serialVersionUID = 1L; <span style="white-space:pre"> </span>public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { <span style="white-space:pre"> </span>String sessionCode = (String) request.getSession().getAttribute("session_vcode"); <span style="white-space:pre"> </span>String paramCode = request.getParameter("verifyCode"); <span style="white-space:pre"> </span>if (paramCode == null || paramCode.trim().isEmpty()) { <span style="white-space:pre"> </span>request.setAttribute("msg", "验证码不能为空!");// msg用于在jsp界面回显 <span style="white-space:pre"> </span>request.getRequestDispatcher("/register.jsp").forward(request,response); <span style="white-space:pre"> </span>} else if (paramCode.length() != 4) { <span style="white-space:pre"> </span>request.setAttribute("msg", "验证码长度必须为4!"); <span style="white-space:pre"> </span>request.getRequestDispatcher("/register.jsp").forward(request,response); <span style="white-space:pre"> </span>} else if (!paramCode.equalsIgnoreCase(sessionCode)) { <span style="white-space:pre"> </span>request.setAttribute("msg", "验证码错误!"); <span style="white-space:pre"> </span>request.getRequestDispatcher("/register.jsp").forward(request,response); <span style="white-space:pre"> </span>return; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>request.getRequestDispatcher("/success.jsp").forward(request, response); <span style="white-space:pre"> </span>} }</span>