一、什么是圖片驗證碼?
可以參考下面這張圖:
我們在一些網站注冊的時候,經常需要填寫以上圖片的信息。
1、圖片生成實體類:
1 package com.hexianwei.graphic; 2 3 import java.awt.Color; 4 import java.awt.Font; 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 16 public class ImageVerificationCode { 17 18 private int weight = 100; //驗證碼圖片的長和寬 19 private int height = 40; 20 private String text; //用來保存驗證碼的文本內容 21 private Random r = new Random(); //獲取隨機數對象 22 //private String[] fontNames = {"宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312"}; //字體數組 23 //字體數組 24 private String[] fontNames = {"Georgia"}; 25 //驗證碼數組 26 private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; 27 28 /** 29 * 獲取隨機的顏色 30 * 31 * @return 32 */ 33 private Color randomColor() { 34 int r = this.r.nextInt(225); //這里為什么是225,因為當r,g,b都為255時,即為白色,為了好辨認,需要顏色深一點。 35 int g = this.r.nextInt(225); 36 int b = this.r.nextInt(225); 37 return new Color(r, g, b); //返回一個隨機顏色 38 } 39 40 /** 41 * 獲取隨機字體 42 * 43 * @return 44 */ 45 private Font randomFont() { 46 int index = r.nextInt(fontNames.length); //獲取隨機的字體 47 String fontName = fontNames[index]; 48 int style = r.nextInt(4); //隨機獲取字體的樣式,0是無樣式,1是加粗,2是斜體,3是加粗加斜體 49 int size = r.nextInt(10) + 24; //隨機獲取字體的大小 50 return new Font(fontName, style, size); //返回一個隨機的字體 51 } 52 53 /** 54 * 獲取隨機字符 55 * 56 * @return 57 */ 58 private char randomChar() { 59 int index = r.nextInt(codes.length()); 60 return codes.charAt(index); 61 } 62 63 /** 64 * 畫干擾線,驗證碼干擾線用來防止計算機解析圖片 65 * 66 * @param image 67 */ 68 private void drawLine(BufferedImage image) { 69 int num = r.nextInt(10); //定義干擾線的數量 70 Graphics2D g = (Graphics2D) image.getGraphics(); 71 for (int i = 0; i < num; i++) { 72 int x1 = r.nextInt(weight); 73 int y1 = r.nextInt(height); 74 int x2 = r.nextInt(weight); 75 int y2 = r.nextInt(height); 76 g.setColor(randomColor()); 77 g.drawLine(x1, y1, x2, y2); 78 } 79 } 80 81 /** 82 * 創建圖片的方法 83 * 84 * @return 85 */ 86 private BufferedImage createImage() { 87 //創建圖片緩沖區 88 BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB); 89 //獲取畫筆 90 Graphics2D g = (Graphics2D) image.getGraphics(); 91 //設置背景色隨機 92 g.setColor(new Color(255, 255, r.nextInt(245) + 10)); 93 g.fillRect(0, 0, weight, height); 94 //返回一個圖片 95 return image; 96 } 97 98 /** 99 * 獲取驗證碼圖片的方法 100 * 101 * @return 102 */ 103 public BufferedImage getImage() { 104 BufferedImage image = createImage(); 105 Graphics2D g = (Graphics2D) image.getGraphics(); //獲取畫筆 106 StringBuilder sb = new StringBuilder(); 107 for (int i = 0; i < 4; i++) //畫四個字符即可 108 { 109 String s = randomChar() + ""; //隨機生成字符,因為只有畫字符串的方法,沒有畫字符的方法,所以需要將字符變成字符串再畫 110 sb.append(s); //添加到StringBuilder里面 111 float x = i * 1.0F * weight / 4; //定義字符的x坐標 112 g.setFont(randomFont()); //設置字體,隨機 113 g.setColor(randomColor()); //設置顏色,隨機 114 g.drawString(s, x, height - 5); 115 } 116 this.text = sb.toString(); 117 drawLine(image); 118 return image; 119 } 120 121 /** 122 * 獲取驗證碼文本的方法 123 * 124 * @return 125 */ 126 public String getText() { 127 return text; 128 } 129 130 public static void output(BufferedImage image, OutputStream out) throws IOException //將驗證碼圖片寫出的方法 131 { 132 ImageIO.write(image, "JPEG", out); 133 } 134 }
2、在控制器中把圖片響應給前端頁面
1 @RequestMapping("getVerifiCode") 2 @ResponseBody 3 public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException { 4 /* 5 1.生成驗證碼 6 2.把驗證碼上的文本存在session中 7 3.把驗證碼圖片發送給客戶端 8 */ 9 ImageVerificationCode ivc = new ImageVerificationCode(); //用我們的驗證碼類,生成驗證碼類對象 10 BufferedImage image = ivc.getImage(); //獲取驗證碼 11 request.getSession().setAttribute("text", ivc.getText()); //將驗證碼的文本存在session中 12 ivc.output(image, response.getOutputStream());//將驗證碼圖片響應給客戶端 13 }
3、從session獲得驗證碼字符
1 @RequestMapping("Login_authentication") 2 @ResponseBody 3 public String Login_authentication(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { 4 request.setCharacterEncoding("utf-8"); 5 String session_vcode=(String) request.getSession().getAttribute("text"); //從session中獲取真正的驗證碼 6 return session_vcode; 7 }
4、前端請求圖片
1 <a href="javascript:getVerifiCode()"> 2 <img id="yzm_img" style="cursor:pointer;width: 100px;height: 36px;margin: 5px 0 0 5px;border-radius: 3px;" title="點擊刷新驗證碼" src="Mcake/getVerifiCode"/> 3 </a> 4 function getVerifiCode() { 5 $("#yzm_img").prop('src','Mcake/getVerifiCode?a='+new Date().getTime()); 6 }