JavaWeb---制作验证码

来源:互联网 发布:中国历史 知乎 编辑:程序博客网 时间:2024/05/23 18:33
 

JavaWeb---制作验证码

 469人阅读 评论(1) 收藏 举报
 分类:

目录(?)[+]


说起验证码,绝壁是个让人蛋疼的问题,特别是节假日在12306上面抢票的时候遇到的外星系验证码,大大降低了用户的体验度!
可是作为我辈中人,还是要知道验证码为毛存在,其作用是什么!
如果再想深究,那么坐下来,让我们好好探讨探讨如何制作验证码!请跟我来……

验证码形式

字母数字组合、加减法、中英文、算式加减法……


 

为什么需要验证码

验证码降低了用户体验度,但是为什么存在呢???

如果没有验证码:

1)       对特定用户不断登录破解密码

2)       对某个网站创建账户

3)       对某个网站提交垃圾数据

4)       都某个网站刷票

如果存在验证码:

只有人亲自识别验证码,输入验证码内容,才能登录、发评论等等,防止计算机破解自动登录发灌水帖等;通过验证码来区分人和计算机;

 


制作验证码

验证码包含两部分:输入框和显示验证码的图片;

一般验证机制如下图:


可是,显示验证码的图片是如何产生的呢?


通过Servlet手工制作验证码(简单型)

1)       手工生成的验证码比较简单,用到的类有

2)       BufferedImage图像数据缓冲区

3)       Graphics绘制图片

4)       Color获取颜色

5)       Random生成随机数

6)       ImageIO输出图片


 

ImageServlet类:

[java] view plain copy
 print?
  1. package hdu.terence;  
  2.    
  3. import java.awt.Color;  
  4. import java.awt.Graphics;  
  5. import java.awt.image.BufferedImage;  
  6. import java.io.IOException;  
  7. import java.io.PrintWriter;  
  8. import java.util.Random;  
  9.    
  10. import javax.imageio.ImageIO;  
  11. import javax.servlet.ServletException;  
  12. import javax.servlet.http.HttpServlet;  
  13. importjavax.servlet.http.HttpServletRequest;  
  14. importjavax.servlet.http.HttpServletResponse;  
  15.    
  16. public class ImageServlet extendsHttpServlet {  
  17.    
  18.        publicImageServlet() {  
  19.               super();  
  20.        }  
  21.    
  22.        publicvoid destroy() {  
  23.               super.destroy();  
  24.        }  
  25.        publicvoid doGet(HttpServletRequest request, HttpServletResponse response)  
  26.                      throwsServletException, IOException {  
  27.               BufferedImagebi=new BufferedImage(68,22,BufferedImage.TYPE_INT_RGB);  
  28.               Graphicsg=bi.getGraphics();  
  29.               Colorc=new Color(200,150,255);  
  30.               g.setColor(c);  
  31.               g.fillRect(0,06822);  
  32.               char[]ch="WQERTYUIOPASDFG127890HJKLZ3456XCVBNMmnbvcxzkjhgfdsaqwertyuiop".toCharArray();  
  33.               Randomr=new Random();  
  34.               intlen=ch.length,index;  
  35.                
  36.               StringBuffersb=new StringBuffer();//用于保存图片  
  37.               for(inti=0;i<4;i++)  
  38.               {  
  39.                      index=r.nextInt(len);  
  40.                      g.setColor(newColor(r.nextInt(88),r.nextInt(188),r.nextInt(255)));  
  41.                      g.drawString(ch[index]+"",(i*15)+318);  
  42.                      sb.append(ch[index]);  
  43.               }  
  44.               request.getSession().setAttribute("verifyCode",sb.toString());  
  45.               ImageIO.write(bi,"JPG", response.getOutputStream());  
  46.        }  
  47.        publicvoid doPost(HttpServletRequest request, HttpServletResponse response)  
  48.                      throwsServletException, IOException {  
  49.        }  
  50.        publicvoid init() throws ServletException {  
  51.                
  52.        }  
  53. }  


 

LoginServlet类:

[java] view plain copy
 print?
  1. package hdu.terence;  
  2.    
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.    
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. importjavax.servlet.http.HttpServletRequest;  
  9. importjavax.servlet.http.HttpServletResponse;  
  10.    
  11. public class LoginServlet extendsHttpServlet {  
  12.    
  13.         
  14.        publicLoginServlet() {  
  15.               super();  
  16.        }  
  17.        publicvoid destroy() {  
  18.        }  
  19.        publicvoid doGet(HttpServletRequest request, HttpServletResponse response)  
  20.                      throwsServletException, IOException {  
  21.               response.setContentType("text/html;charset=gbk");  
  22.               StringverifyCode=(String) request.getSession().getAttribute("verifyCode");  
  23.               StringcheckCode=request.getParameter("checkCode");  
  24.               verifyCode=verifyCode.toUpperCase();  
  25.               checkCode=checkCode.toUpperCase();  
  26.                
  27.               PrintWriterout=response.getWriter();  
  28.               if(checkCode.equals(verifyCode))  
  29.               {  
  30.                      out.println("niece!验证码输入正确!");  
  31.               }  
  32.               else  
  33.               {  
  34.                      out.println("你似不似撒?验证码都能输入错误!!!!!!");  
  35.               }  
  36.               out.flush();  
  37.               out.close();  
  38.        }  
  39.        publicvoid doPost(HttpServletRequest request, HttpServletResponse response)  
  40.                      throwsServletException, IOException {  
  41.        }  
  42.        publicvoid init() throws ServletException {       }  
  43. }  


 

JSP:

[javascript] view plain copy
 print?
  1. <head>   
  2. <script type="text/javascript">  
  3.    function reloadVerifyCode()  
  4.     {  
  5.       var time =new Date().getTime();  
  6.       document.getElementById("imageCode")  
  7.       document.getElementById("imageCode").src="<%=request.getContextPath()%>/servlet/ImageServlet?d="+time;  
  8.       //加time传递参数是为了区分请求连接,重新获取验证码;  
  9.     }  
  10.    </script>  
  11.   </head>  
  12.   <body>  
  13.   <form action="<%=request.getContextPath() %>/servlet/LoginServlet" method="get">  
  14.       验证码:<input type="text" name="checkCode"id="checkCode">  
  15.       <img alt="验证码" id="imageCode"src="<%=request.getContextPath() %>/servlet/ImageServlet"/>  
  16.       <a href="javascript:reloadVerifyCode();">看不清,重新获取</a><br>  
  17.          <input type="submit"name="submit" value="确定">   
  18.       <input type="reset"name="submit" value="重置">  
  19.         
  20.     </form>  
  21.   </body>  


结果




通过Kaptcha开源组件制作验证码(花式验证码)

Kaptcha:这个工具是可配置的,可以生成各种花式的验证码,可通过配置参数增加机器识别难度。

 

准备步骤:

1)       下载kaptcha-2.3.jar(点击下载kaptcha-2.3.jar

2)       将jar包导入项目,添加到路径

3)       编写页面

4)       配置web.xml

5)       启动项目



 

数字、英文混合验证

Step1 JSP

[html] view plain copy
 print?
  1. <table>  
  2.       <tr>  
  3.         <th>输入验证码:</th>  
  4.         <th align="left" > <input name="checkCode"Id="checkCode" type="text"/></th>  
  5.       </tr>  
  6.       <tr>  
  7.         <th> </th>  
  8.         <th><img  src="randomcode.jpg">看不清,重换一张 </th>  
  9.       </tr>  
  10.       <tr>  
  11.           <th> </th>  
  12.         <th align="left">  
  13.         <input type="submit" value="确定"/>     
  14.         <input type="reset" value="重置"/>  
  15.         </th>  
  16.       </tr>  
  17.       </table>  


src:连接到后台生成的randomcode.jpg;


Step2  在web.xml中添加映射配置:

 

[html] view plain copy
 print?
  1. <servlet-mapping>  
  2.   <servlet-name>kaptcha</servlet-name>  
  3.   <url-pattern>/randomcode.jpg</url-pattern>  
  4. </servlet-mapping>  


 

 

Step3  增加配置参数,防止机器识别图片

可配置的参数如下:

-

[html] view plain copy
 print?
  1. <span style="color:#000000;"><init-param>  
  2.   <description>图片边框,合法值:yes , no</description>  
  3.   <param-name>kaptcha.border</param-name>  
  4.   <param-value>yes</param-value>  
  5.   </init-param>  
  6. -<init-param>  
  7.   <description>边框颜色,合法值: r,g,b (and optional alpha) 或者white,black,blue.</description>  
  8.   <param-name>kaptcha.border.color</param-name>  
  9.   <param-value>red</param-value>  
  10.   </init-param>  
  11. -<init-param>  
  12.   <description>边框厚度,合法值:>0</description>  
  13.   <param-name>kaptcha.border.thickness</param-name>  
  14.   <param-value>2</param-value>  
  15.   </init-param>  
  16. -<init-param>  
  17.   <description>图片宽 200</description>  
  18.   <param-name>kaptcha.image.width</param-name>  
  19.   <param-value>150</param-value>  
  20.   </init-param>  
  21. -<init-param>  
  22.   <description>图片高 50</description>  
  23.   <param-name>kaptcha.image.height</param-name>  
  24.   <param-value>50</param-value>  
  25.   </init-param>  
  26. -<init-param>  
  27.   <description>图片实现类</description>  
  28.   <param-name>kaptcha.producer.impl</param-name>  
  29.   <param-value>com.google.code.kaptcha.impl.DefaultKaptcha</param-value>  
  30.   </init-param>  
  31. -<init-param>  
  32.   <description>不用文本实现:com.google.code.kaptcha.impl.DifaultTextCreator用文本实现:则用自己重写的中文类(内含算法)ChineseTextCheck.ChineseTextCode</description>  
  33.   <param-name>kaptcha.textproducer.impl</param-name>  
  34.   <param-value>ChineseTextCheck.ChineseTextCode</param-value>  
  35.   </init-param>  
  36. -<init-param>  
  37.   <description>文本集合,验证码值从此集合中获取</description>  
  38.   <param-name>kaptcha.textproducer.char.string</param-name>  
  39.   <param-value>qwertys1zcmd2345s67g890</param-value>  
  40. <!-- 
  41. <param-value>abcde2345678gfynmnpwx</param-value> 
  42.   -->  
  43. <!-- 
  44. <param-value>你好我好大家好</param-value> 
  45.   -->  
  46.   </init-param>  
  47. -<init-param>  
  48.   <description>验证码长度 5</description>  
  49.   <param-name>kaptcha.textproducer.char.length</param-name>  
  50.   <param-value>5</param-value>  
  51.   </init-param>  
  52. -<init-param>  
  53.   <description>字体Arial, Courier</description>  
  54.   <param-name>kaptcha.textproducer.font.names</param-name>  
  55.   <param-value>Arial, Courier</param-value>  
  56.   </init-param>  
  57. -<init-param>  
  58.   <description>字体大小 40px.</description>  
  59.   <param-name>kaptcha.textproducer.font.size</param-name>  
  60.   <param-value>30</param-value>  
  61.   </init-param>  
  62. -<init-param>  
  63.   <description>字体颜色,合法值: r,g,b 或者 white,black,blue.</description>  
  64.   <param-name>kaptcha.textproducer.font.color</param-name>  
  65.   <param-value>black</param-value>  
  66.   </init-param>  
  67. -<init-param>  
  68.   <description>文字间隔 2</description>  
  69.   <param-name>kaptcha.textproducer.char.space</param-name>  
  70.   <param-value>2</param-value>  
  71.   </init-param>  
  72. -<init-param>  
  73.   <description>干扰实现类</description>  
  74.   <param-name>kaptcha.noise.impl</param-name>  
  75. -<param-value>  
  76. <!-- 
  77.  com.google.code.kaptcha.impl.NoNoise 
  78.   -->  
  79.   com.google.code.kaptcha.impl.DefaultNoise  
  80.   </param-value>  
  81.   </init-param>  
  82. -<init-param>  
  83.   <description>干扰颜色,合法值: r,g,b 或者 white,black,blue.</description>  
  84.   <param-name>kaptcha.noise.color</param-name>  
  85.   <param-value>blue</param-value>  
  86.   </init-param>  
  87. -<init-param>  
  88.   <description>图片样式: 水纹com.google.code.kaptcha.impl.WaterRipple鱼眼com.google.code.kaptcha.impl.FishEyeGimpy阴影com.google.code.kaptcha.impl.ShadowGimpy</description>  
  89.   <param-name>kaptcha.obscurificator.impl</param-name>  
  90.   <param-value>com.google.code.kaptcha.impl.FishEyeGimpy</param-value>  
  91.   </init-param>  
  92. -<init-param>  
  93.   <description>背景实现类</description>  
  94.   <param-name>kaptcha.background.impl</param-name>  
  95.   <param-value>com.google.code.kaptcha.impl.DefaultBackground</param-value>  
  96.   </init-param>  
  97. -<init-param>  
  98.   <description>背景颜色渐变,开始颜色</description>  
  99.   <param-name>kaptcha.background.clear.from</param-name>  
  100.   <param-value>red</param-value>  
  101.   </init-param>  
  102. -<init-param>  
  103.   <description>背景颜色渐变,结束颜色</description>  
  104.   <param-name>kaptcha.background.clear.to</param-name>  
  105.   <param-value>white</param-value>  
  106.   </init-param>  
  107. -<init-param>  
  108.   <description>文字渲染器</description>  
  109.   <param-name>kaptcha.word.impl</param-name>  
  110.   <param-value>com.google.code.kaptcha.text.impl.DefaultWordRenderer</param-value>  
  111.   </init-param>  
  112. -<init-param>  
  113.   <description>session中存放验证码的key键</description>  
  114.   <param-name>kaptcha.session.key</param-name>  
  115.   <param-value>KAPTCHA_SESSION_KEY</param-value>  
  116.   </init-param>  
  117. -<init-param>  
  118.   <description>The date the kaptcha is generatedis put into the HttpSession. This is the key value for that item in thesession.</description>  
  119.   <param-name>kaptcha.session.date</param-name>  
  120.   <param-value>KAPTCHA_SESSION_DATE</param-value>  
  121.   </init-param></span>  

 

Step 4  结果

 



中文验证码

Step1  重写配置文件里面的TextProducer类

 

[java] view plain copy
 print?
  1. import java.util.Random;  
  2. import com.google.code.kaptcha.text.TextProducer;  
  3. importcom.google.code.kaptcha.util.Configurable;  
  4.    
  5. public class ChineseTextCode extendsConfigurable implements TextProducer {  
  6.    
  7.        /* 
  8.         * 中文验证码(non-Javadoc) 
  9.         * 粘贴以下算法重写文本实现类 
  10.         * @see com.google.code.kaptcha.text.TextProducer#getText() 
  11.         */  
  12.        publicString getText() {  
  13.               intlength = getConfig().getTextProducerCharLength();  
  14.               StringfinalWord = "", firstWord = "";  
  15.               inttempInt = 0;  
  16.               String[]array = { "0""1""2""3","4""5""6""7""8","9",  
  17.                             "a","b""c""d""e""f" };  
  18.    
  19.               Randomrand = new Random();  
  20.    
  21.               for(int i = 0; i < length; i++) {  
  22.                      switch(rand.nextInt(array.length)) {  
  23.                      case1:  
  24.                             tempInt= rand.nextInt(26) + 65;  
  25.                             firstWord= String.valueOf((char) tempInt);  
  26.                             break;  
  27.                      case2:  
  28.                             intr1,  
  29.                             r2,  
  30.                             r3,  
  31.                             r4;  
  32.                             StringstrH,  
  33.                             strL;//high&low  
  34.                             r1= rand.nextInt(3) + 11// 前闭后开[11,14)  
  35.                             if(r1 == 13) {  
  36.                                    r2= rand.nextInt(7);  
  37.                             }else {  
  38.                                    r2= rand.nextInt(16);  
  39.                             }  
  40.    
  41.                             r3= rand.nextInt(6) + 10;  
  42.                             if(r3 == 10) {  
  43.                                    r4= rand.nextInt(15) + 1;  
  44.                             }else if (r3 == 15) {  
  45.                                    r4= rand.nextInt(15);  
  46.                             }else {  
  47.                                    r4= rand.nextInt(16);  
  48.                             }  
  49.    
  50.                             strH= array[r1] + array[r2];  
  51.                             strL= array[r3] + array[r4];  
  52.    
  53.                             byte[]bytes = new byte[2];  
  54.                             bytes[0]= (byte) (Integer.parseInt(strH, 16));  
  55.                             bytes[1]= (byte) (Integer.parseInt(strL, 16));  
  56.    
  57.                             firstWord= new String(bytes);  
  58.                             break;  
  59.                      default:  
  60.                             tempInt= rand.nextInt(10) + 48;  
  61.                             firstWord= String.valueOf((char) tempInt);  
  62.                             break;  
  63.                      }  
  64.                      finalWord+= firstWord;  
  65.               }  
  66.               returnfinalWord;  
  67.        }  
  68.    
  69.        publicString getText1() {  
  70.               intlength = getConfig().getTextProducerCharLength();  
  71.               //char[]charS = getConfig().getTextProducerCharString();  
  72.                
  73.               String[]s = new String[]{"我","是","阿","S","靖","卡","哥","滚","蛋","呸"};  
  74.    
  75.               Randomrand = new Random();  
  76.               StringBuffersb = new StringBuffer();  
  77.               for(inti = 0; i < length; i++){  
  78.                      intind =rand.nextInt(s.length);  
  79.                      sb.append(s[ind]);  
  80.               }  
  81.               returnsb.toString();  
  82.        }  
  83. }  


Step2  然后修改配置文件web.xml

[html] view plain copy
 print?
  1. <init-param>  
  2.         <description>文本实现类</description>  
  3.         <param-name>kaptcha.textproducer.impl</param-name>  
  4.         <param-value>  
  5.            ChineseTextCheck.ChineseTextCode  
  6.         </param-value>  
  7. </init-param>  


Step 3  结果




算式验证码

以重写Servlet的方式实现算式验证码

步骤:

1)       获取随机数值,结果相加

2)       将计算公式写到图片上

3)       将相加结果保存到session中

4)       依此为目标重写KapthaServlet类

 

Step1  重写KaptchaServlet

[java] view plain copy
 print?
  1. package formula;  
  2.    
  3. import com.google.code.kaptcha.Producer;  
  4. import com.google.code.kaptcha.util.Config;  
  5. import java.awt.image.BufferedImage;  
  6. import java.io.IOException;  
  7. import java.util.Enumeration;  
  8. import java.util.Properties;  
  9. import javax.imageio.ImageIO;  
  10. import javax.servlet.Servlet;  
  11. import javax.servlet.ServletConfig;  
  12. import javax.servlet.ServletException;  
  13. import javax.servlet.ServletOutputStream;  
  14. import javax.servlet.http.HttpServlet;  
  15. import javax.servlet.http.HttpServletRequest;  
  16. importjavax.servlet.http.HttpServletResponse;  
  17. import javax.servlet.http.HttpSession;  
  18.    
  19. public class KaptchaServlet extendsHttpServlet implements Servlet {  
  20.        privateProperties props;  
  21.        privateProducer kaptchaProducer;  
  22.        privateString sessionKeyValue;  
  23.    
  24.        publicKaptchaServlet() {  
  25.               this.props= new Properties();  
  26.    
  27.               this.kaptchaProducer= null;  
  28.    
  29.               this.sessionKeyValue= null;  
  30.        }  
  31.    
  32.        publicvoid init(ServletConfig conf) throws ServletException {  
  33.               super.init(conf);  
  34.    
  35.               ImageIO.setUseCache(false);  
  36.    
  37.               EnumerationinitParams = conf.getInitParameterNames();  
  38.               while(initParams.hasMoreElements()) {  
  39.                      Stringkey = (String) initParams.nextElement();  
  40.                      Stringvalue = conf.getInitParameter(key);  
  41.                      this.props.put(key,value);  
  42.               }  
  43.    
  44.               Configconfig = new Config(this.props);  
  45.               this.kaptchaProducer= config.getProducerImpl();  
  46.               this.sessionKeyValue= config.getSessionKey();  
  47.        }  
  48.    
  49.        publicvoid doGet(HttpServletRequest req, HttpServletResponse resp)  
  50.                      throwsServletException, IOException {  
  51.               resp.setDateHeader("Expires",0L);  
  52.    
  53.               resp.setHeader("Cache-Control","no-store, no-cache, must-revalidate");  
  54.    
  55.               resp.addHeader("Cache-Control","post-check=0, pre-check=0");  
  56.    
  57.               resp.setHeader("Pragma","no-cache");  
  58.    
  59.               resp.setContentType("image/jpeg");  
  60.    
  61.               StringcapText = this.kaptchaProducer.createText();  
  62.               Strings1 = capText.substring(01);  
  63.               Strings2 = capText.substring(12);  
  64.               intr = Integer.valueOf(s1).intValue() + Integer.valueOf(s2).intValue();  
  65.    
  66.               req.getSession().setAttribute(this.sessionKeyValue,String.valueOf(r));  
  67.    
  68.               BufferedImagebi = this.kaptchaProducer.createImage(s1+"+"+s2+"=?");  
  69.    
  70.               ServletOutputStreamout = resp.getOutputStream();  
  71.    
  72.               ImageIO.write(bi,"jpg", out);  
  73.               try{  
  74.                      out.flush();  
  75.               }finally {  
  76.                      out.close();  
  77.               }  
  78.        }  
  79. }  


Step2  配置web.xml

[html] view plain copy
 print?
  1. <servlet-name>kaptcha</servlet-name>  
  2.        <description>文字、数字英文方式:com.google.code.kaptcha.servlet.KaptchaServlet  
  3.                  算式:使用自己重写的类:formula.KaptchaServlet  
  4.        </description>  
  5. <servlet-class>formula.KaptchaServlet</servlet-class>  


上述中formula.KaptchaServlet是指自己在formula包下重写的KaptchaServlet类。

Step3  结果



References Demo

参考源码:verifyCode
原创粉丝点击