以前碰到注冊登入需要圖形驗證碼的時候,一般都是到網絡上直接淘一個,也不讀代碼,直接就用了,今天靜下來,從頭到尾讀了一遍代碼,自己又照着寫了一遍,加上了完整的注釋,下面介紹步驟,首先建立一個web項目,src建立一個class類:
1 import java.awt.BasicStroke;
2 import java.awt.Color;
3 import java.awt.Font;
4 import java.awt.Graphics;
5 import java.awt.Graphics2D;
6 import java.awt.image.BufferedImage;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.util.Random;
12
13 import javax.imageio.ImageIO;
14
15 public class VCode {
16
17 private int w;// 圖檔寬
18 private int h;// 圖檔高
19 private Color bgColor = new Color(240, 240, 240);// 背景色
20 private Random random = new Random();// 随機數對象
21 // 設定字型範圍
22 private String[] fontNames = { "宋體", "華文楷體", "黑體", "華文新魏", "華文隸書", "微軟雅黑",
23 "楷體" };
24 //設定字型樣式範圍
25 private int[] fontstyles = { 0, 1, 2, 3 };
26 //設定字号範圍
27 private int[] fontSizes={24,25,26,27,28};
28 //設定所有字元串範圍
29 private String codes="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
30
31
32 //無參構造方法
33 public VCode() {
34 }
35
36 //帶寬和高的構造函數
37 public VCode(int w, int h) {
38 super();
39 this.w = w;
40 this.h = h;
41 }
42
43
44 // 傳回一張背景圖檔
45 private BufferedImage createImage() {
46 /**
47 * 1:建立圖檔 2:設定背景色
48 */
49 // 1:建立圖檔
50 BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
51 // 2:設定背景色
52 Graphics g = img.getGraphics();
53 g.setColor(bgColor);
54 g.fillRect(0, 0, w, h);
55
56 return img;
57 }
58
59 // 随機傳回字型顔色
60 private Color randomColor() {
61 int r = random.nextInt(256);
62 int g = random.nextInt(256);
63 int b = random.nextInt(256);
64 return new Color(r, g, b);
65 }
66
67 // 随機傳回字型樣式
68 private Font randomFont() {
69 //随機生成字型下标,随機從給定的範圍内擷取一個字型
70 int index=random.nextInt(fontNames.length);
71 String name=fontNames[index];
72
73 //随機生成字型樣式下表,随機從給定的傳回内擷取到一個字型樣式
74 index=random.nextInt(fontstyles.length);
75 int style = fontstyles[index];
76
77 //随機生成字型大小下标,随機從給定的傳回内擷取到一個字型大小
78 index=random.nextInt(fontSizes.length);
79 int size = fontSizes[index];
80
81 return new Font(name, style, size);
82 }
83
84 // 随機傳回字型内容
85 private String randomChar() {
86 int index=random.nextInt(codes.length());
87
88 return codes.charAt(index)+"";
89 }
90
91 //随即傳回幾條幹擾線
92 private void getLine(BufferedImage img){
93 //設定幹擾線的寬度為1.5倍寬,随機畫五條
94 Graphics2D g=(Graphics2D)img.getGraphics();
95 g.setColor(Color.BLACK);
96 g.setStroke(new BasicStroke(1.5f));
97 for(int i=0;i<5;i++){
98 int x1=random.nextInt(w);
99 int y1=random.nextInt(h);
100 int x2=random.nextInt(w);
101 int y2=random.nextInt(h);
102 g.drawLine(x1, y1, x2, y2);
103
104 }
105
106 }
107 // 使用者調用該方法擷取圖檔
108 public BufferedImage getImage() {
109 /**
110 * 随機生成字元,字元範圍0-9A-Za-z, 設定字型,字号,是否粗體 都是随機 字元的顔色
111 */
112 BufferedImage img = createImage();
113
114 this.getLine(img);
115 // 擷取畫筆
116 Graphics g = img.getGraphics();
117 // 畫内容
118 for (int i = 0; i < 4; i++) {
119 g.setColor(this.randomColor());// 擷取随機顔色
120 g.setFont(this.randomFont());// 擷取随機字型
121 g.drawString(this.randomChar(), w / 4 * i, h - 5);// 擷取字元串随機内容
122 }
123 return img;
124 }
125
126 //使用者調用該方法儲存圖檔到本地
127 public void saveImage(BufferedImage img,OutputStream ous){
128
129 try {
130 ImageIO.write(img, "JPEG", ous);
131 } catch (FileNotFoundException e) {
132 e.printStackTrace();
133 } catch (IOException e) {
134 e.printStackTrace();
135 }
136 }
137 }
接下來建立一個servlet:
1 package com.wang.verifySode;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.image.BufferedImage;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.PrintWriter;
10
11 import javax.imageio.ImageIO;
12 import javax.servlet.ServletException;
13 import javax.servlet.http.HttpServlet;
14 import javax.servlet.http.HttpServletRequest;
15 import javax.servlet.http.HttpServletResponse;
16
17 public class BServlet extends HttpServlet {
18
19 public void doGet(HttpServletRequest request, HttpServletResponse response)
20 throws ServletException, IOException {
21
22 VCode v=new VCode(70, 35);
23 BufferedImage img=v.getImage();
24 v.saveImage(img, response.getOutputStream());
25
26 }
27
28 }
在你需要加驗證碼的地方,如注冊頁面中适當地方加入:
<img id="img" alt="" src="/tools/BServlet"><a href="javascript:changeNext()">看不清楚,換一張</a>
這裡需要說一下,因為驗證碼有一個"看不清楚 換一張"的功能,是以需要加一個javascript函數,如下:
<script type="text/javascript">
function changeNext(){
var a=document.getElementById("img");
a.src="/tools/BServlet?a="+new Date().getTime();
}
</script>
為了避免浏覽器的圖檔緩存問題而導緻點選後無法随機下一張圖檔,這裡在超連結後面加一個永不重複的參數,可以避免這個問題,見上面代碼.
配置項目,開浏覽器,運作,完美~