1.驗證碼的生成,我們能夠看到是用Graphics對象畫出來的。對象我們必須要獲得Graphics對象
1-1、Graphics對象的獲取,要通過BufferedImage獲得
1
2
3
4
|
<span style= "font-size:18px;" > int width= 100 ; //確定框框的大小 int height= 40 ; BufferedImage bfi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g=bfi.getGraphics(); //獲得Graphics對象就可以畫圖</span> |
1-2、一般的驗證碼背景框都是白色的
1
2
3
|
<span style= "font-size:18px;" > //1,設置背景(白框框) g.setColor(Color.WHITE); //白色的畫筆 g.fillRect( 0 , 0 , width, height); //畫矩形矩形框框</span> |
1-3、保存數據(后臺驗證使用)和設置字體樣式(美觀)
1
2
3
4
|
String str= "" ; //保存數據 Random rom= new Random(); //設置字體的大寫與粗 g.setFont( new Font( "a" , Font.BOLD, 20 )); |
1-4、生成具體的數值,以及隨機生成的顏色
1
2
3
4
5
6
|
for (int i=0;i<4;i++){ int num=rom.nextInt(10); //生成的隨機數 g.setColor( new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256))); //設置畫筆的顏色(隨機) g.drawString( "" +num, 20*i, 20+rom.nextInt(10)); //畫出線,x的位置每一之間增加20,y的坐標以20一條線,在線上或者是線下 //PS:位置需要明確些, } |
1-5、一般的數字容易被其他軟件直接識別出來,為了防黑。稍微加一點干擾線
1
2
3
4
5
|
//畫出一些干擾線 for ( int i = 0 ; i < 10 ; i++) { g.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ), rom.nextInt( 256 ))); //設置畫筆的顏色(隨機) g.drawLine(rom.nextInt( 100 ),rom.nextInt( 40 ), rom.nextInt( 100 ), rom.nextInt( 40 )); //位置也是隨機,x,y的值不要超過矩形框框 } |
1-6、銷毀Graphics對象和存儲圖片
1
2
|
<span style= "white-space:pre" > </span>g.dispose(); //銷毀對象 ImageIO.write(bfi, "JPEG" , res.getOutputStream()); //圖片用字節流 直接得到 PS::: res是Servlet里面的。 |
這樣驗證碼就生成了,那我們如何導入到前臺去呢
2、具體實現
前臺代碼呈現():
1
2
3
4
5
6
7
|
< body > < h1 >用戶登錄</ h1 >< br /> 用戶名:< input type = "text" name = "nametext" />< br /> 密 碼:< input type = "text" name = "psd" />< br /> 請輸入驗證碼:< input type = "text" /> < img <span style = "color:#ff0000;" >src="/IMG/immg" </ span >id="aid"/>< a href = "javascript:flush()" >看不清</ a > </ body > |
src的地址來源就是從后臺發過來的。路徑是很有意思的。
2-1步驟
項目里面
myeclipse --> src -->new Servlet 出現如下:
點擊----》next 出現如下頁面:
這個配置會自動到項目里面的web-INF文件夾里面web.xml。這個框框里面的值就是前臺 src里面寫的需要訪問的路徑,----> 點擊完成就行了。
自動了。生成如下界面:
在這里就可寫之前的代碼。但是需要注意,我們必須通過覆蓋這個方法才能有效:
1
2
3
4
5
6
|
protected void service(HttpServletRequest req, HttpServletResponse resp) //自動生成 輸入 <span style="font-family: Arial, Helvetica, sans-serif;">service 補全,自動生成</span> throws ServletException, IOException { // TODO Auto-generated method stub super .service(req, resp); } |
具體的代碼如下:
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
|
package cn.hncu.com.servlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Imgdemo extends HttpServlet { @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { int width= 100 ; //確定框框的大小 int height= 40 ; BufferedImage bfi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g=bfi.getGraphics(); //獲得Graphics對象就可以畫圖 //1,設置背景(白框框) g.setColor(Color.WHITE); //白色的畫筆 g.fillRect( 0 , 0 , width, height); //畫矩形矩形框框 //2,具體生成隨機數 String str= "" ; //保存數據 Random rom= new Random(); //設置字體的大寫與粗 g.setFont( new Font( "a" , Font.BOLD, 20 )); //畫出具體的圖片 for ( int i= 0 ;i< 4 ;i++){ int num=rom.nextInt( 10 ); //生成的隨機數 g.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ), rom.nextInt( 256 ))); //設置畫筆的顏色(隨機) g.drawString( "" +num, 20 *i, 20 +rom.nextInt( 10 )); //畫出線,x的位置每一之間增加20,y的坐標以20一條線,在線上或者是線下 //PS:位置需要明確些, } //畫出一些干擾線 for ( int i = 0 ; i < 10 ; i++) { g.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ), rom.nextInt( 256 ))); //設置畫筆的顏色(隨機) g.drawLine(rom.nextInt( 100 ),rom.nextInt( 40 ), rom.nextInt( 100 ), rom.nextInt( 40 )); //位置也是隨機,x,y的值不要超過矩形框框 } g.dispose(); ImageIO.write(bfi, "JPEG" , res.getOutputStream()); //圖片用字節流 直接得到 } }<span style= "font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);" > </span> |
前臺代碼:
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
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> < html > < head > < base href="<%=basePath%>"> < title >My JSP 'img.jsp' starting page</ title > < meta http-equiv = "pragma" content = "no-cache" > < meta http-equiv = "cache-control" content = "no-cache" > < meta http-equiv = "expires" content = "0" > < meta http-equiv = "keywords" content = "keyword1,keyword2,keyword3" > < meta http-equiv = "description" content = "This is my page" > <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> < script type = "text/javascript" > function flush(){ var text=document.getElementById("aid"); var date =new Date(); var tt=date.getTime(); text.src="/IMG/immg?"+tt; } </ script > </ head > < body > < h1 >用戶登錄</ h1 >< br /> 用戶名:< input type = "text" name = "nametext" />< br /> 密 碼:< input type = "text" name = "psd" />< br /> 請輸入驗證碼:< input type = "text" /> < img src = "/IMG/immg" id = "aid" />< a href = "javascript:flush()" >看不清</ a > </ body > </ html > |
對于前臺代碼需要解釋一下:
當我們的的驗證碼傳過來看不清的時候需要刷新,而瀏覽器有自動記憶的功能,當沒有新的參數傳進來的時候,瀏覽器是不會刷新的,所以我們需要手動的去寫一個js控制參數傳,我們知道,只有時間是不會變化的,所有我們采用時間來作為參數傳遞。
PS:自己坑了一段時間的問題:驗證碼的路徑問題。前端的“/”表示 tomcat目錄,在項目內部,如web.xml中“/”表示該項目下。也就是說,他們兩個的目錄差了一層。
最后附上自己在測試的時候的代碼以及修改數字形狀的問題,如改成2D的效果更不錯。都有很明顯的記錄。
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
|
package cn.hncu.com; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import org.junit.Test; public class Demoimg { @Test public void Test() throws Exception{ String str= "9988" ; int width= 60 ; int height= 30 ; //通過bufferedImage對象獲得Graphics對象 BufferedImage bfi= new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); Graphics g=bfi.getGraphics(); g.drawString(str, 10 , 10 ); g.dispose(); //類似于IO中的關流 ImageIO.write(bfi , "JPEG" , new FileOutputStream( "F:\\ex\\a.jpg" )); //bfi為畫布,將畫布寫到文件中JPEG為指定文件格式 } @Test public void Test2() throws Exception{ int width= 100 ; int height= 40 ; BufferedImage bfi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g=bfi.getGraphics(); //獲得Graphics對象就可以畫圖 //1,設置背景(白框框) g.setColor(Color.WHITE); //白色的畫筆 g.fillRect( 0 , 0 , width, height); //2,具體生成隨機數 String str= "" ; //保存數據 Random rom= new Random(); //設置字體的大寫與粗 g.setFont( new Font( "a" , Font.BOLD, 20 )); //畫出具體的圖片 for ( int i= 0 ;i< 4 ;i++){ int num=rom.nextInt( 10 ); //生成的隨機數 g.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ), rom.nextInt( 256 ))); //設置畫筆的顏色(隨機) g.drawString( "" +num, 20 *i, 20 +rom.nextInt( 10 )); //畫出線,x的位置每一之間增加20,y的坐標以20一條線,在線上或者是線下 //PS:位置需要明確些, } //畫出一些干擾線 for ( int i = 0 ; i < 10 ; i++) { g.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ), rom.nextInt( 256 ))); //設置畫筆的顏色(隨機) g.drawLine(rom.nextInt( 100 ),rom.nextInt( 40 ), rom.nextInt( 100 ), rom.nextInt( 40 )); //位置也是隨機,x,y的值不要超過矩形框框 } g.dispose(); ImageIO.write(bfi, "JPEG" , new FileOutputStream( "F:\\ex\\b.jpg" )); } //畫出可以變化的情況 //字體能夠旋轉的驗證碼 @Test public void Test3() throws IOException{ int width= 100 ; int height= 40 ; BufferedImage bfi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g=bfi.getGraphics(); Graphics2D g2d=(Graphics2D) g; Random rom = new Random(); g2d.setColor(Color.WHITE); //設置畫筆的顏色 g2d.fillRect( 0 , 0 , width, height); //畫出一個白色的矩形 g2d.setFont( new Font( "a" , Font.BOLD, 20 )); for ( int i= 0 ;i< 4 ;i++){ int num=rom.nextInt( 10 ); //旋轉,放縮 AffineTransform aff= new AffineTransform(); //aff.rotate(Math.random(), i*18, height-20);//旋轉 aff.scale( 0.6 +Math.random(), 0.6 +Math.random()); //縮放 g2d.setColor( new Color(rom.nextInt( 256 ),rom.nextInt( 256 ),rom.nextInt( 256 ))); g2d.setTransform(aff); g2d.drawString( "" +num, i* 18 , height- 25 ); } g2d.dispose(); ImageIO.write(bfi, "JPEG" , new FileOutputStream( "F:\\ex\\c.jpg" )); } } |
以上就是關于java生成驗證碼的基本流程,還附帶了自己親自的測試的代碼,希望這些都能幫到大家。