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

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

验证码生成器:

[html] view plain copy

print?

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

下面是页面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. }
 // 刷新图片              function changeImg() {                  var imgSrc = $("#imgObj");                  var url = imgSrc.attr("src");                 imgSrc.attr("src", changeUrl(url));              }              //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳              function changeUrl(url) {                  var timestamp = (new Date()).valueOf();                  var index = url.indexOf("?");                console.log(index);                 if (index > 0) {                      url = url.substring(0, url.indexOf("?"));                  }                console.log(url);                if ((url.indexOf("&") > 0)) {                      url = url + "×tamp=" + timestamp;                      console.log(url);                } else {                      url = url + "?timestamp=" + timestamp;                    console.log(url);                }                  return url;              }

下面是controller层输出验证码

[java] view plain copy

print?

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

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

[java] view plain copy

print?

  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. }
String code = request.getParameter("code");  HttpSession session = request.getSession();  String sessionCode = (String) session.getAttribute("code");  if (!StringUtils.equalsIgnoreCase(code, sessionCode)) {  //忽略验证码大小写      throw new RuntimeException("验证码对应不上code=" + code + "  sessionCode=" + sessionCode);  } 

原文地址:https://www.cnblogs.com/jpfss/p/8444116.html

时间: 2024-09-30 06:41:28

java图形验证码生成工具类及web页面校验验证码的相关文章

java中常用的工具类(三)

继续分享java中常用的一些工具类.前两篇的文章中有人评论使用Apache 的lang包和IO包,或者Google的Guava库.后续的我会加上的!谢谢支持IT江湖 一.连接数据库的综合类 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

java中常用的工具类(二)

下面继续分享java中常用的一些工具类,希望给大家带来帮助! 1.FtpUtil Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

java中常用的工具类

一.String工具类 package com.itjh.javaUtil; import java.util.ArrayList; import java.util.List; /** * * String工具类. <br> * * @author 宋立君 * @date 2014年06月24日 */ public class StringUtil { private static final int INDEX_NOT_FOUND = -1; private static final St

分享万能java字符串编码转换工具类

代码下载地址:http://www.zuidaima.com/share/1795356301560832.htm 原文:分享万能java字符串编码转换工具类 package com.zuidaima.util; import java.io.UnsupportedEncodingException; /** * 转换字符串的编码 */ public class ChangeCharset { /** 7位ASCII字符,也叫作ISO646-US.Unicode字符集的基本拉丁块 */ publ

二维码生成工具类

1 package com.ideal.common.util; 2 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.FileOutputStream; 8 import java.util.UUID; 9 10 import net.glx

Java常用正则表达式验证工具类RegexUtils.java

原文:Java常用正则表达式验证工具类RegexUtils.java 源代码下载地址:http://www.zuidaima.com/share/1550463379442688.htm Java 表单注册常用正则表达式验证工具类,常用正则表达式大集合. 1. 电话号码 2. 邮编 3. QQ 4. E-mail 5. 手机号码 6. URL 7. 是否为数字 8. 是否为中文 9. 身份证 10. 域名 11. IP .... 常用验证应有尽有! 这的确是您从事 web 开发,服务器端表单验证

ZXing 二维码解析生成工具类

原文:http://www.open-open.com/code/view/1455848023292 import com.google.zxing.*; import com.google.zxing.Reader; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.googl

Java 后台验证的工具类

Java 后台验证的工具类 public class ValidationUtil {         //手机号     public static String mobile = "^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\\d{8}$";       //不允许为空     public static String blank = ".*[^ ].*";  

Java学习-049-正则工具类

自去年九月份决定再次入学和职业资格进阶,开始备战二者考试至今,以及当下进行中的职称申请,犹如孤独的狼,不断前行在路上,而今凡凡总总的已历8月... 不感慨了,如下为一园友需要的正则工具类,直接上码: 1 public class RegUtils { 2 private static Logger logger = Logger.getLogger(RegUtils.class.getName()); 3 private static String msg = ""; 4 privat