1. 使用Servlet实现验证码
首先创建工程,实现jsp代码:
<script type="text/javascript"> function reloadCode() { var time = new Date().getTime(); document.getElementById("image_code").src = "<%=path%>/servlet/ImageServlet?d=" + time; } </script> </head> <body> 验证码: <input type="text" name="check_code"> <img id="image_code" alt="验证码" src="<%=request.getContextPath()%>/servlet/ImageServlet"> <a href="javascript:reloadCode();">看不清楚</a> <br> </body>
重新加载的函数有一个d的参数,这是为了防止传相同的地址浏览器无法刷新。可以看出我们的img标签使用的是Servlet来填充的,接下来是我们的ImageServlet:
<span style="white-space:pre"> </span>protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB); Graphics g = bi.getGraphics(); Color c = new Color(200, 150, 255); g.setColor(c); g.fillRect(0, 0, 68, 22); // 生成26个英文字母的数组 char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); // 随机获取4个字符 Random r = new Random(); int len = ch.length; int index = 0; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 4; i++) { index = r.nextInt(len); g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255))); g.drawString(ch[index] + "", i * 15 + 3, 18); sb.append(ch[index]); } req.getSession().setAttribute("check_code", sb.toString()); ImageIO.write(bi, "JPG", resp.getOutputStream()); }
只用重写Servlet的doGet方法就可以了。
接下来是验证验证码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); String checkCode = (String) request.getSession().getAttribute( "check_code"); String userCode = request.getParameter("check_code"); PrintWriter out = response.getWriter(); if (checkCode.equals(userCode)) { out.print("验证码输入正确"); } else { out.print("验证码输入错误"); } out.close(); }
如果不想区分大小写的话,在获取userCode的时候可以统一转换成大写即可。
2. 使用Jcaptcha组件实现验证码
Jcaptcha是一个用来生成图形验证码的Java开源组件,使用起来也是非常的简单方便。常常与Spring组合使用,可以产生多种形式的验证码。
Jcaptcha是一个开源的组件,先是jsp代码:
<form action="submit.action" method="post"> <img src="jcaptcha.jpg" /> <input type="text" name="japtcha" value="" /> <input type="submit"/> </form>
然后需要导入几个这个开源的jar包,后面工程里都有。
然后配置web.xml
<web-app> <display-name>Simple Image Captcha Servlet Sample</display-name> <servlet> <servlet-name>jcaptcha</servlet-name> <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class> </servlet> <servlet> <servlet-name>submit</servlet-name> <servlet-class>com.octo.captcha.module.servlet.image.sample.SubmitActionServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>jcaptcha</servlet-name> <url-pattern>/jcaptcha.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>submit</servlet-name> <url-pattern>/submit.action</url-pattern> </servlet-mapping> </web-app>
最后是提交servlet的代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String userCaptchaResponse = request.getParameter("japtcha"); boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse( request, userCaptchaResponse); if (captchaPassed) response.getWriter().write("captcha passed"); else { response.getWriter().write("captcha failed"); } response.getWriter().write("<a href='index.jsp'>Try again</a>"); }
也是很简单。
3. 使用Kaptcha实现验证码
Kaptcha也是一个非常实用的验证码生成工具,有了它,你可以生成各种样式的验证码,因为它是可配置的。
(1). 首先是字母数组组合验证
先导入包kaptcha-2.3.jar,index.jsp:
<form action="check.jsp"> <img src="randomcode.jpg"> <input type="text" name="r"> <input type="submit" name="s"> <br> </form>
在web.xml重配置:
<servlet> <servlet-name>kaptcha</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>kaptcha</servlet-name> <url-pattern>/randomcode.jpg</url-pattern> </servlet-mapping>
检测验证码是否正确的check.jsp:
<% // 检查是否是正确的验证码 String k = (String) session .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); String str = request.getParameter("r"); if (k.equals(str)) { out.print("true"); } out.print(k + "---" + str); %>
(2). Kaptcha的详细配置
在web.xml中的<servlet>标签的<init-param>标签内,可以配置多个设置:
1). 是否加入边框:
<description>图片边框,合法值:yes,no</description> <param-name>kaptcha.border</param-name> <param-value>yes</param-value>
2). 设置边框颜色:
<description>边框颜色,合法值:white、black、blue等</description> <param-name>kaptcha.border.color</param-name> <param-value>black</param-value>
3). 边框厚度:
<description>边框厚度,合法值:0等</description> <param-name>kaptcha.border.thickness</param-name> <param-value>1</param-value>
3). 图片宽度:
<description>图片宽度</description> <param-name>kaptcha.image.width</param-name> <param-value>100</param-value>
4). 图片高度:
<description>图片高度</description> <param-name>kaptcha.image.height</param-name> <param-value>50</param-value>
5). 图片实现类:
<description>图片实现类</description> <param-name>kaptcha.producer.impl</param-name> <param-value>com.google.code.kaptcha.implDefaultKaptcha</param-value>
6). 文本实现类:
<description>文本实现类</description> <param-name>kaptcha.textproducer.impl</param-name> <param-value>com.google.code.kaptcha.text.implDefaultTextCreator</param-value>
7). 验证码配置:
<description>文本集合,验证码值从此集合中获取</description> <param-name>kaptcha.textproducer.char.string</param-name> <param-value>abcde234567gfmnopq</param-value>
8). 验证码长度:
<description>验证码长度 5</description> <param-name>kaptcha.textproducer.char.length</param-name> <param-value>2</param-value>
9). 验证码字体:
<description>字体Arial,Courier</description> <param-name>kaptcha.textproducer.font.names</param-name> <param-value>Arial, Courier</param-value>
10). 验证码字体大小:
<description>字体大小40px</description> <param-name>kaptcha.textproducer.font.size</param-name> <param-value>40</param-value>
11). 验证码字体颜色:
<description>字体颜色,合法值:white、black等</description> <param-name>kaptcha.textproducer.font.color</param-name> <param-value>black</param-value>
12). 验证码文字间隔:
<description>文字间隔</description> <param-name>kaptcha.textproducer.char.space</param-name> <param-value>2</param-value>
13). 验证码干扰实现类:
<description>干扰实现类</description> <param-name>kaptcha.noise.impl</param-name> <param-value>com.google.code.kaptcha.impl.DefaultNoise</param-value>
14). 干扰颜色:
<description>干扰颜色,合法值:r, g, b或者black等</description> <param-name>kaptcha.noise.color</param-name> <param-value>black</param-value>
15). 验证码图片样式:
<description>图片样式:水纹com.google.code.kaptcha.impl.WaterRipple、鱼眼com.google.code.kaptcha.impl.FishEyeGimpy、阴影com.google.code.kaptcha.impl.ShadowGimpy等</description> <param-name>kaptcha.obscurificator.impl</param-name> <param-value>com.google.code.kaptcha.impl.WaterRipple</param-value>
16). 背景实现类:
<description>背景实现类</description> <param-name>kaptcha.background.impl</param-name> <param-value>com.google.code.kaptcha.impl.DefaultBackground</param-value>
17). 背景颜色渐变-开始颜色:
<description>颜色渐变-开始颜色</description> <param-name>kaptcha.background.clear.from</param-name> <param-value>green</param-value>
18). 背景颜色渐变-结束颜色:
<description>颜色渐变-结束颜色</description> <param-name>kaptcha.background.clear.to</param-name> <param-value>white</param-value>
19). 文字渲染器:
<description>文字渲染器</description> <param-name>kaptcha.word.impl</param-name> <param-value>com.google.code.kaptcha.text.impl.DefaultWordRenderer</param-value>
20). 验证码在session中存放验证码的key键配置:
<description>session中存放验证码的key键</description> <param-name>kaptcha.session.key</param-name> <param-value>KAPTCHA_SESSION_KEY</param-value>
(3). 中文验证码的实现
首先是我们生成中文的类:
public class ChineseText extends Configurable implements TextProducer { public String getText() { int length = getConfig().getTextProducerCharLength(); String finalWord = "", firstWord = ""; int tempInt = 0; String[] array = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; Random rand = new Random(); for (int i = 0; i < length; i++) { switch (rand.nextInt(array.length)) { case 1: tempInt = rand.nextInt(26) + 65; firstWord = String.valueOf((char) tempInt); break; case 2: int r1, r2, r3, r4; String strH, strL;// high&low r1 = rand.nextInt(3) + 11; // 前闭后开[11,14) if (r1 == 13) { r2 = rand.nextInt(7); } else { r2 = rand.nextInt(16); } r3 = rand.nextInt(6) + 10; if (r3 == 10) { r4 = rand.nextInt(15) + 1; } else if (r3 == 15) { r4 = rand.nextInt(15); } else { r4 = rand.nextInt(16); } strH = array[r1] + array[r2]; strL = array[r3] + array[r4]; byte[] bytes = new byte[2]; bytes[0] = (byte) (Integer.parseInt(strH, 16)); bytes[1] = (byte) (Integer.parseInt(strL, 16)); firstWord = new String(bytes); break; default: tempInt = rand.nextInt(10) + 48; firstWord = String.valueOf((char) tempInt); break; } finalWord += firstWord; } return finalWord; } }
需要继承Configurable类,实现TextProducer接口。然后在web.xml中配置:
<init-param> <description>文本实现类</description> <param-name>kaptcha.textproducer.impl</param-name> <param-value>com.thr.text.ChineseText</param-value> </init-param>
注意我们这里要指定类的全名。
如果当输入中文检测出现乱码时,修改check.jsp:
<% // 检查是否是正确的验证码 String k = (String) session .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); String str = request.getParameter("r"); str = new String(str.getBytes("ISO-8859-1"), "UTF-8"); if (k.equals(str)) { out.print("true"); } out.print(k + "---" + str); %>
(4). 算式验证码的实现
我们要写一个Servlet来实现:
public class KaptchaServlet extends HttpServlet implements Servlet { private Properties props; private Producer kaptchaProducer; private String sessionKeyValue; public KaptchaServlet() { this.props = new Properties(); this.kaptchaProducer = null; this.sessionKeyValue = null; } public void init(ServletConfig conf) throws ServletException { super.init(conf); ImageIO.setUseCache(false); Enumeration initParams = conf.getInitParameterNames(); while (initParams.hasMoreElements()) { String key = (String) initParams.nextElement(); String value = conf.getInitParameter(key); this.props.put(key, value); } Config config = new Config(this.props); this.kaptchaProducer = config.getProducerImpl(); this.sessionKeyValue = config.getSessionKey(); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setDateHeader("Expires", 0L); resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); resp.addHeader("Cache-Control", "post-check=0, pre-check=0"); resp.setHeader("Pragma", "no-cache"); resp.setContentType("image/jpeg"); String capText = this.kaptchaProducer.createText(); String s1 = capText.substring(0, 1); String s2 = capText.substring(1, 2); int r = Integer.valueOf(s1).intValue() + Integer.valueOf(s2).intValue(); req.getSession().setAttribute(this.sessionKeyValue, String.valueOf(r)); BufferedImage bi = this.kaptchaProducer.createImage(s1 + "+" + s2 + "=?"); ServletOutputStream out = resp.getOutputStream(); ImageIO.write(bi, "jpg", out); try { out.flush(); } finally { out.close(); } } }
然后在web.xml中替换掉我们之前使用的servlet即可。
版权声明:本文为博主原创文章,未经博主允许不得转载。