Java web 开发: 随机生成验证码,支持大小写字母、数字;随机字体

来源:互联网 发布:美乐网络官方 编辑:程序博客网 时间:2024/05/18 03:44

http://blog.csdn.net/ibm_hoojo/article/details/5834509

[java] view plaincopyprint?
  1. java随机产生验证码,可以随机生成数字、大写字母、小写字母。还可以随机生成文字字体、及大小。在图片上面可能字体都不不同、大小不等。  
  2.   
  3. package com.hoo.util;  
  4.   
  5.   
  6. import java.awt.Color;  
  7. import java.awt.Font;  
  8. import java.awt.Graphics;  
  9. import java.awt.image.BufferedImage;  
  10. import java.util.Random;  
  11.   
  12. import javax.imageio.ImageIO;  
  13. import javax.servlet.http.HttpServletRequest;  
  14. import javax.servlet.http.HttpServletResponse;  
  15. /** 
  16.  * <b>function:</b> 验证码生成工具类 
  17.  * @project NetWorkService 
  18.  * @package com.hoo.util  
  19.  * @fileName ValidCodeUtils.java 
  20.  * @createDate 2010-8-3 下午03:05:50 
  21.  * @author hoojo 
  22.  */  
  23. @SuppressWarnings("unused")  
  24. public class ValidCodeUtils {  
  25.     /********************************************************************* 
  26.      * 验证码宽度 
  27.      */  
  28.     public static int WIDTH = 60;  
  29.     /*** 
  30.      * 验证码高度 
  31.      */  
  32.     public static int HEIGHT = 20;  
  33.       
  34.     /********************************************************************** 
  35.      * 验证码背景颜色COLOR_FC_BG 应当小于COLOR_BC_BG 
  36.      */  
  37.     public static int COLOR_FC_BG = 200;  
  38.     /*** 
  39.      * 验证码背景颜色COLOR_FC_BG 应当小于COLOR_BC_BG 
  40.      */  
  41.     public static int COLOR_BC_BG = 250;  
  42.       
  43.     /********************************************************************** 
  44.      * 验证码背景干扰线颜色COLOR_FC_LINE 应当小于COLOR_BC_LINE 
  45.      */  
  46.     public static int COLOR_FC_LINE = 160;  
  47.     /*** 
  48.      * 验证码背景干扰线颜色COLOR_FC_LINE 应当小于COLOR_BC_LINE 
  49.      */  
  50.     public static int COLOR_BC_LINE = 200;  
  51.       
  52.     /*************************************************************************** 
  53.      * 验证码颜色COLOR_FC_CODE 应当小于COLOR_BC_CODE 
  54.      */  
  55.     public static int COLOR_FC_CODE = 20;  
  56.     /*** 
  57.      * 验证码颜色COLOR_FC_CODE 应当小于COLOR_BC_CODE 
  58.      */  
  59.     public static int COLOR_BC_CODE = 170;  
  60.       
  61.     /*************************************************************************** 
  62.      * 生成在指定范围内的颜色 
  63.      * @param fc 范围fc color值 小于255 
  64.      * @param bc 范围bc color值 小于255 
  65.      * @return Color 
  66.      */  
  67.     private static Color getRandColor(int fc, int bc) {  
  68.         Random random = new Random();  
  69.         if (fc < 0)  
  70.             fc = 0;  
  71.         if (bc < 0)  
  72.             bc = 1;  
  73.         if (fc > 255)  
  74.             fc = 255;  
  75.         if (bc > 255)  
  76.             bc = 255;  
  77.         if (bc == fc)   
  78.             bc += 10;  
  79.         int temp = 0;  
  80.         if (bc < fc) {  
  81.             temp = bc;  
  82.             bc = fc;  
  83.             fc = temp;  
  84.         }  
  85.         int r = fc + random.nextInt(bc - fc);  
  86.         int g = fc + random.nextInt(bc - fc);  
  87.         int b = fc + random.nextInt(bc - fc);  
  88.         return new Color(r, g, b);  
  89.     }  
  90.   
  91.     /** 
  92.      * <b>function:</b> 生成图片方法 
  93.      * @createDate 2010-8-3 下午03:06:22 
  94.      * @author hoojo 
  95.      * @param request HttpServletRequest 
  96.      * @param response HttpServletResponse 
  97.      * @return boolean 
  98.      * @throws Exception 
  99.      */  
  100.     public static boolean getImage(HttpServletRequest request, HttpServletResponse response) throws Exception{  
  101.         response.reset();  
  102.         response.setContentType("image/jpeg");  
  103.         // 设置页面不缓存  
  104.         response.setHeader("Pragma""No-cache");  
  105.         response.setHeader("Cache-Control""no-cache");  
  106.         response.setDateHeader("Expires"0);  
  107.         // 在内存中创建图象       
  108.         BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);  
  109.   
  110.         // 获取图形上下文  
  111.         Graphics img = image.getGraphics();  
  112.         // 生成随机类  
  113.         Random random = new Random();  
  114.   
  115.         // 设定背景色  
  116.         img.setColor(getRandColor(COLOR_FC_BG, COLOR_BC_BG));  
  117.         img.fillRect(00, WIDTH, HEIGHT);  
  118.   
  119.         // 设定字体  
  120.         img.setFont(new Font("Times New Roman", Font.PLAIN, 18));  
  121.   
  122.         // 画边框  
  123.         // g.setColor(new Color());  
  124.         // g.drawRect(0,0,width-1,height-1);  
  125.   
  126.         // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到  
  127.         img.setColor(getRandColor(COLOR_FC_LINE, COLOR_BC_LINE));  
  128.         for (int i = 0; i < 155; i++) {  
  129.             int x = random.nextInt(WIDTH);  
  130.             int y = random.nextInt(HEIGHT);  
  131.             int xl = random.nextInt(12);  
  132.             int yl = random.nextInt(12);  
  133.             img.drawLine(x, y, x + xl, y + yl);  
  134.         }  
  135.   
  136.         // 取随机产生的认证码(4位数字)  
  137.         String codeValue = "";  
  138.         for (int i = 0; i < 4; i++) {  
  139.             //String rand = String.valueOf(random.nextInt(10));  
  140.             String rand = getRandomChar();  
  141.             codeValue = codeValue.concat(rand);  
  142.             img.setFont(getRandomFont());//随机字体  
  143.             // 将认证码显示到图象中  
  144.             img.setColor(getRandColor(COLOR_FC_CODE, COLOR_BC_CODE));  
  145.             img.drawString(rand, 13 * i + 616);  
  146.         }  
  147.         request.getSession().setAttribute("codeValue", codeValue);  
  148.         // 图象生效  
  149.         img.dispose();  
  150.         // 输出图象到页面  
  151.         return ImageIO.write(image, "JPEG", response.getOutputStream());  
  152.     }  
  153.       
  154.     /** 
  155.      * 随机生成字符,含大写、小写、数字 
  156.      * <b>function:</b> 功能 
  157.      * @createDate 2010-8-23 上午10:33:55 
  158.      * @author hoojo 
  159.      * @return 
  160.      */  
  161.     public static String getRandomChar() {  
  162.         int index = (int) Math.round(Math.random() * 2);  
  163.         String randChar = "";  
  164.         switch (index) {  
  165.         case 0://大写字符  
  166.             randChar = String.valueOf((char)Math.round(Math.random() * 25 + 65));  
  167.             break;  
  168.         case 1://小写字符  
  169.             randChar = String.valueOf((char)Math.round(Math.random() * 25 + 97));  
  170.             break;  
  171.         default://数字  
  172.             randChar = String.valueOf(Math.round(Math.random() * 9));  
  173.             break;  
  174.         }  
  175.         return randChar;  
  176.     }  
  177.       
  178.     /** 
  179.      * <b>function:</b> 随机生成字体、文字大小 
  180.      * @createDate 2010-8-23 上午10:44:22 
  181.      * @author hoojo 
  182.      * @return 
  183.      */  
  184.     public static Font getRandomFont() {  
  185.         String[] fonts = {"Georgia""Verdana""Arial""Tahoma""Time News Roman""Courier New""Arial Black""Quantzite"};  
  186.         int fontIndex = (int)Math.round(Math.random() * (fonts.length - 1));  
  187.         int fontSize = (int) Math.round(Math.random() * 4 + 16);  
  188.         return new Font(fonts[fontIndex], Font.PLAIN, fontSize);  
  189.     }  
  190. }  

其中验证码的值是保存在session中:request.getSession().setAttribute("codeValue", codeValue);
比较用户输入的值和session中的codeValue是否相等即可;

下面是jsp页面调用servlet:ValidCodeServlet.java

ValidCodeServlet中调用了上面的ValidCodeUtils 验证码生成工具类

[java] view plaincopyprint?
  1. package com.hoo.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import com.hoo.util.ValidCodeUtils;  
  10.   
  11. @SuppressWarnings("serial")  
  12. public class ValidCodeServlet extends HttpServlet {  
  13.       
  14.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  15.             throws ServletException, IOException {  
  16.         try {  
  17.             ValidCodeUtils.getImage(request, response);  
  18.         } catch (Exception e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.     }  
  22.   
  23.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  24.             throws ServletException, IOException {  
  25.         doGet(request, response);  
  26.     }  
  27. }  

 

jsp页面调用servlet方法即可

 

[xhtml] view plaincopyprint?
  1. js:reloadValidCode方法  
  2.   
  3. function reloadValidCode(o) {  
  4.     o.src = "${pageContext.request.contextPath }/validCodeServlet?timed=" + new Date().getMilliseconds();  
  5. }  
  6. 这里的"timed=" + new Date().getMilliseconds();是需要防止IE缓存用的  
  7.   
  8. html标签:  
  9. <img src="${pageContext.request.contextPath }/validCodeServlet" title="看不清,点击刷新" onclick="reloadValidCode(this)"/>  
  10. 直接跟Servlet名称配置的url即可,和web.xml配置对应。主要调用路径${pageContext.request.contextPath }/validCodeServlet这样会带上根目录,比较保险。  
  11.   
  12. web.xml中validCodeServlet配置  
  13. <servlet>  
  14.     <servlet-name>validCodeServlet</servlet-name>  
  15.     <servlet-class>com.hoo.servlet.ValidCodeServlet</servlet-class>  
  16. </servlet>  
  17.   
  18. <servlet-mapping>  
  19.     <servlet-name>validCodeServlet</servlet-name>  
  20.     <url-pattern>/validCodeServlet</url-pattern>  
  21. </servlet-mapping>  

 

至此,整个图片验证码就配置完毕。在浏览器中输入你请求的url,在jsp页面中就可以看到效果

 

怎样,效果还很理想吧。字体、大小、数字、大小写字符、及颜色等!