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




 

分类: 我的技术总结(13) 


版权声明:本文为博主原创文章,未经博主允许不得转载。


最近要用到图形验证码,上网查找资料,参考改了一个工具类,并添加到程序中,下面记录下来以做备份,主要参考http://www.iteye.com/topic/573456文章进行的修改,添加了注释,和web页面校验验证码



[java]  view plain  copy

 

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


下面是页面调用验证码

[html]  view plain  copy

 

        
1. <div class="form-group  col-lg-6">  
2. <label for="id" class="col-sm-4 control-label">  
3.         验证码:  
4. </label>  
5. <div class="col-sm-8">  
6. <input type="text" id="code" name="code" class="form-control" style="width:250px;"/>  
7. <img id="imgObj" alt="验证码" src="/article/validateCode" onclick="changeImg()"/>  
8. <a href="#" onclick="changeImg()">换一张</a>  
9. </div>  
10. </div>  
11.   
12. <script type="text/javascript">  
13.     // 刷新图片  
14.     function changeImg() {  
15. imgSrc = $("#imgObj");  
16. src = imgSrc.attr("src");  
17.         imgSrc.attr("src", changeUrl(src));  
18.     }  
19.     //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳  
20.     function changeUrl(url) {  
21. timestamp = (new Date()).valueOf();  
22. index = url.indexOf("?",url);  
23. > 0) {  
24. url = url.substring(0, url.indexOf(url, "?"));  
25.         }  
26. >= 0)) {  
27. url = url + "×tamp=" + timestamp;  
28.         } else {  
29. url = url + "?timestamp=" + timestamp;  
30.         }  
31.         return url;  
32.     }  
33. </script>



下面是controller层输出验证码


[java]  view plain  copy

 

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


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


    [java]  view plain  copy

     

    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. }



    最近要用到图形验证码,上网查找资料,参考改了一个工具类,并添加到程序中,下面记录下来以做备份,主要参考http://www.iteye.com/topic/573456文章进行的修改,添加了注释,和web页面校验验证码



    [java]  view plain  copy

     

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


    下面是页面调用验证码

    [html]  view plain  copy

            
    1. <div class="form-group  col-lg-6">  
    2. <label for="id" class="col-sm-4 control-label">  
    3.         验证码:  
    4. </label>  
    5. <div class="col-sm-8">  
    6. <input type="text" id="code" name="code" class="form-control" style="width:250px;"/>  
    7. <img id="imgObj" alt="验证码" src="/article/validateCode" onclick="changeImg()"/>  
    8. <a href="#" onclick="changeImg()">换一张</a>  
    9. </div>  
    10. </div>  
    11.   
    12. <script type="text/javascript">  
    13.     // 刷新图片  
    14.     function changeImg() {  
    15. imgSrc = $("#imgObj");  
    16. src = imgSrc.attr("src");  
    17.         imgSrc.attr("src", changeUrl(src));  
    18.     }  
    19.     //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳  
    20.     function changeUrl(url) {  
    21. timestamp = (new Date()).valueOf();  
    22. index = url.indexOf("?",url);  
    23. > 0) {  
    24. url = url.substring(0, url.indexOf(url, "?"));  
    25.         }  
    26. >= 0)) {  
    27. url = url + "×tamp=" + timestamp;  
    28.         } else {  
    29. url = url + "?timestamp=" + timestamp;  
    30.         }  
    31.         return url;  
    32.     }  
    33. </script>



    下面是controller层输出验证码


    [java]  view plain  copy

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

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


    [java]  view plain  copy

     

            
    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. }