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