java图形验证码生成工具类及web页面校验验证码

最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善。

验证码生成器:

  1. import javax.imageio.ImageIO;    
  2. import java.awt.*;    
  3. import java.awt.image.BufferedImage;    
  4. import java.io.FileOutputStream;    
  5. import java.io.IOException;    
  6. import java.io.OutputStream;    
  7. import java.util.Date;    
  8. import java.util.Random;    
  9.     
  10. /**   
  11.  * 验证码生成器   
  12.  *   
  13.  * @author    
  14.  */    
  15. public class ValidateCode {    
  16.     // 图片的宽度。    
  17.     private int width = 160;    
  18.     // 图片的高度。    
  19.     private int height = 40;    
  20.     // 验证码字符个数    
  21.     private int codeCount = 5;    
  22.     // 验证码干扰线数    
  23.     private int lineCount = 150;    
  24.     // 验证码    
  25.     private String code = null;    
  26.     // 验证码图片Buffer    
  27.     private BufferedImage buffImg = null;    
  28.     
  29.     // 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)    
  30.     private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',    
  31.             'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',    
  32.             'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'};    
  33.     
  34.     /**   
  35.      * 默认构造函数,设置默认参数   
  36.      */    
  37.     public ValidateCode() {    
  38.         this.createCode();    
  39.     }    
  40.     
  41.     /**   
  42.      * @param width  图片宽   
  43.      * @param height 图片高   
  44.      */    
  45.     public ValidateCode(int width, int height) {    
  46.         this.width = width;    
  47.         this.height = height;    
  48.         this.createCode();    
  49.     }    
  50.     
  51.     /**   
  52.      * @param width     图片宽   
  53.      * @param height    图片高   
  54.      * @param codeCount 字符个数   
  55.      * @param lineCount 干扰线条数   
  56.      */    
  57.     public ValidateCode(int width, int height, int codeCount, int lineCount) {    
  58.         this.width = width;    
  59.         this.height = height;    
  60.         this.codeCount = codeCount;    
  61.         this.lineCount = lineCount;    
  62.         this.createCode();    
  63.     }    
  64.     
  65.     public void createCode() {    
  66.         int x = 0fontHeight = 0codeY = 0;    
  67.         int red = 0green = 0blue = 0;    
  68.     
  69.         x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符)    
  70.         fontHeight = height - 2;//字体的高度    
  71.         codeY = height - 4;    
  72.     
  73.         // 图像buffer    
  74.         buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
  75.         Graphics2D g = buffImg.createGraphics();    
  76.         // 生成随机数    
  77.         Random random = new Random();    
  78.         // 将图像填充为白色    
  79.         g.setColor(Color.WHITE);    
  80.         g.fillRect(0, 0, width, height);    
  81.         // 创建字体,可以修改为其它的    
  82.         Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);    
  83. //        Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);    
  84.         g.setFont(font);    
  85.     
  86.         for (int i = 0; i < lineCount; i++) {    
  87.             // 设置随机开始和结束坐标    
  88.             int xs = random.nextInt(width);//x坐标开始    
  89.             int ys = random.nextInt(height);//y坐标开始    
  90.             int xe = xs + random.nextInt(width / 8);//x坐标结束    
  91.             int ye = ys + random.nextInt(height / 8);//y坐标结束    
  92.     
  93.             // 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。    
  94.             red = random.nextInt(255);    
  95.             green = random.nextInt(255);    
  96.             blue = random.nextInt(255);    
  97.             g.setColor(new Color(red, green, blue));    
  98.             g.drawLine(xs, ys, xe, ye);    
  99.         }    
  100.     
  101.         // randomCode记录随机产生的验证码    
  102.         StringBuffer randomCode = new StringBuffer();    
  103.         // 随机产生codeCount个字符的验证码。    
  104.         for (int i = 0; i < codeCount; i++) {    
  105.             String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);    
  106.             // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。    
  107.             red = random.nextInt(255);    
  108.             green = random.nextInt(255);    
  109.             blue = random.nextInt(255);    
  110.             g.setColor(new Color(red, green, blue));    
  111.             g.drawString(strRand, (i + 1) * x, codeY);    
  112.             // 将产生的四个随机数组合在一起。    
  113.             randomCode.append(strRand);    
  114.         }    
  115.         // 将四位数字的验证码保存到Session中。    
  116.         code = randomCode.toString();    
  117.     }    
  118.     
  119.     public void write(String path) throws IOException {    
  120.         OutputStream sos = new FileOutputStream(path);    
  121.         this.write(sos);    
  122.     }    
  123.     
  124.     public void write(OutputStream sos) throws IOException {    
  125.         ImageIO.write(buffImg, "png", sos);    
  126.         sos.close();    
  127.     }    
  128.     
  129.     public BufferedImage getBuffImg() {    
  130.         return buffImg;    
  131.     }    
  132.     
  133.     public String getCode() {    
  134.         return code;    
  135.     }    
  136.     
  137.     /**   
  138.      * 测试函数,默认生成到d盘   
  139.      * @param args   
  140.      */    
  141.     public static void main(String[] args) {    
  142.         ValidateCode vCode = new ValidateCode(160,40,5,150);    
  143.         try {    
  144.             String path="D:/"+new Date().getTime()+".png";    
  145.             System.out.println(vCode.getCode()+" >"+path);    
  146.             vCode.write(path);    
  147.         } catch (IOException e) {    
  148.             e.printStackTrace();    
  149.         }    
  150.     }    
  151. }    

下面是页面JS调用验证码

[javascript] view plain copy
print?
  1. // 刷新图片    
  2.         function changeImg() {    
  3.             var imgSrc = $("#imgObj");    
  4.             var url = imgSrc.attr("src");   
  5.             imgSrc.attr("src", changeUrl(url));    
  6.         }    
  7.         //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳    
  8.         function changeUrl(url) {    
  9.             var timestamp = (new Date()).valueOf();    
  10.             var index = url.indexOf("?");  
  11.             console.log(index);   
  12.             if (index > 0) {    
  13.                 url = url.substring(0, url.indexOf("?"));    
  14.             }  
  15.             console.log(url);  
  16.             if ((url.indexOf("&") > 0)) {    
  17.                 url = url + "×tamp=" + timestamp;    
  18.                 console.log(url);  
  19.             } else {    
  20.                 url = url + "?timestamp=" + timestamp;  
  21.                 console.log(url);  
  22.                 }    
  23.             return url;    
  24.         }  

下面是controller层输出验证码

  1. /  
  2.   响应验证码页面  
  3.   @return  
  4.  */    
  5. @RequestMapping(value="/validateCode")    
  6. public String validateCode(HttpServletRequest request,HttpServletResponse response) throws Exception{    
  7.     // 设置响应的类型格式为图片格式    
  8.     response.setContentType("image/jpeg");    
  9.     //禁止图像缓存。    
  10.     response.setHeader("Pragma""no-cache");    
  11.     response.setHeader("Cache-Control""no-cache");    
  12.     response.setDateHeader("Expires"0);    
  13.     
  14.     HttpSession session = request.getSession();    
  15.     
  16.     ValidateCode vCode = new ValidateCode(120,40,5,100);    
  17.     session.setAttribute("code", vCode.getCode());    
  18.     vCode.write(response.getOutputStream());    
  19.     return null;    
  20. }    

下面是controller层验证验证码输入是否正确

  1. String code = request.getParameter("code");    
  2. HttpSession session = request.getSession();    
  3. String sessionCode = (String) session.getAttribute("code");    
  4. if (!StringUtils.equalsIgnoreCase(code, sessionCode)) {  //忽略验证码大小写    
  5.     throw new RuntimeException("验证码对应不上code=" + code + "  sessionCode=" + sessionCode);    
  6. }   



posted @ 2018-02-12 11:29  星朝  阅读(789)  评论(0编辑  收藏  举报