最近做驗證碼,參考網上案例,發現有不少問題,特意進行了修改和完善。
驗證碼生成器:
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
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調用驗證碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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層輸出驗證碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/** * 響應驗證碼頁面 * @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層驗證驗證碼輸入是否正確
1
2
3
4
5
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); } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。