看了其他人写的验证码程序,于是自己写了个很小的,因为字母就是用ASCii码表示的,那么可以使用int值直接生成就可以了,这样程序很简单,执行效率也很高。
1 ImageOut.java 复则产生验证码
import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.Random; public class ImageOut { private static final int WIDTH = 62; private static final int HEIGHT = 20; private static Color getRandomColor() { Random random = new Random(); return new Color(50 + random.nextInt(100), 50 + random.nextInt(100), 50 + random.nextInt(100)); } private static int getRandomBgInt() { Random random = new Random(); return 180 + random.nextInt(60); } private static Font getRandomFont() { Random random = new Random(); return new Font("Times New Roman", Font.PLAIN, 10 + random.nextInt(8)); } public static char getRandomChar() { Random random = new Random(); if (random.nextInt(5) < 3) { return (char) (65 + random.nextInt(26)); } return (char) (97 + random.nextInt(26)); } public static Pair<String, BufferedImage> getImage() { BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.setColor(new Color(255, getRandomBgInt(), 255)); g.fillRect(0, 0, WIDTH, HEIGHT); StringBuilder s = new StringBuilder(); for (int i = 0; i < 4; i++) { String t = String.valueOf(getRandomChar()); s.append(t); g.setColor(getRandomColor()); g.setFont(getRandomFont()); g.drawString(t, 3 + 16 * i, 18); } g.dispose(); return new Pair<String, BufferedImage>(s.toString(), image); } }
2 上面使用了Pair类,使用Map也可以的,只不过Java里的类都几千行代码的,自己写个可以节约些资源:
Pair.java
public class Pair<K, E> { private K key; private E value; public Pair() { } public Pair(K key, E value) { this.key = key; this.value = value; } public K getKey() { return key; } public void setKey(K key) { this.key = key; } public E getValue() { return value; } public void setValue(E value) { this.value = value; } }
3 在jsp环境中使用上面的程序:
3.1 首先写个为当前用户生成验证码的jsp页面:
ValidateImage.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <%@page import="java.awt.image.BufferedImage,javax.imageio.ImageIO" %> <%@page import="com.bookshop.util.Pair,com.bookshop.util.ImageOut" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <% response.setContentType("image/jpeg"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); Pair<String, BufferedImage> p = ImageOut.getImage(); ImageIO.write(p.getValue(), "JPEG", response.getOutputStream()); session.setAttribute("valid", p.getKey()); %>
3.2 在登录注册的页面中调用:
比如login.jsp
<form id="form1" name="form1" method="post" action="<%=path%>/bookshop/login.jsp"> <input type="hidden" name="op" value="login" readonly="readonly" /> <label></label> <p> <label></label> </p> <p class="STYLE1">用户登录</p> <table width="317"> <tr> <td width="100"><span class="STYLE2">登录名称:</span></td> <td width="200"><input class="field" type="text" name="username" /></td> </tr> <tr> <td><span class="STYLE2">登陆密码:</span></td> <td><input class="field" type="password" name="password" /></td> </tr> <tr> <td rowspan="2"><span class="STYLE2">验证码:</span></td> <td> <input class="field" type="text" name="yanzhm" /> </td> </tr> <tr> <td><img alt="看不清?单击更换!" src="<%=path%>/bookshop/ValidateImage.jsp" onclick="changeValidateCode(this)"/> </td> </tr> <tr> <td> <input class="tijiao" type="submit" name="Submit" value="登 录" /> </td> <td style="text-align:right"> <input type="reset" name="Submit" value="重 置" /> </td> </tr> </table> </form> 上面调用了一个能刷新验证码的js代码:如下 <script type="text/javascript"> function changeValidateCode(obj) { var timenow = new Date().getTime(); obj.src="<%=path%>/bookshop/ValidateImage.jsp?d="+timenow; } </script>
在验证逻辑处只需获取验证就可以了:
String yanzhm = request.getParameter("yanzhm"); String valid = (String) session.getAttribute("valid"); if (!yanzhm.equalsIgnoreCase(valid)) { request.setAttribute("info", "验证码输入错误,请重新输入!"); request.getRequestDispatcher("/bookshop/error.jsp").forward(request, response); return; }
4 在servlet中使用与此类似,此处省略!