所需文件以及技術:javascript
· SecurityUtil.java (後面我會複製給你們)html
· 圖像處理技術java
· 向客戶端輸出io流web
一,實現的原理,當視圖頁面加載的時候經過<img >元素的src屬性去請求得到驗證碼圖片,請求控制層驗證碼生成類隨機生成4個字母或數字(驗證碼長度能夠修改),將生成的驗證碼存儲在session對象裏面,最後經過ImageIO響應給客戶端。ajax
二,實現的步驟:json
1,html: 瀏覽器
<script type="text/javascript"> function reloadCode() { document.getElementById("imgSignCode").src="../signcode/signcode/get.do?r=" + new Date().getTime(); //這裏爲何會加一個時間戳參數呢? 瀏覽器帶有緩存功能 //當一個src中的URL請求一次後,再次請求瀏覽器就不會再去請求得到新數據,而是直接用 //上次請求返回的數據 } </script> <body> <img id="imgSignCode" src="../signcode/signcode/get.do" onclick="reloadCode()" title="從新獲取" style="cursor:pointer;"/> </body>
2,Controller層方法:緩存
/** * ajax獲取驗證碼 */ @ResponseBody @RequestMapping(value = "/getSecurityCode.ajax", produces = {"application/json;charset=UTF-8"}) public void getSecurityCode(HttpServletResponse response, HttpServletRequest request){ // 通知瀏覽器不要緩存 response.setHeader("Expires", "-1"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "-1"); SecurityUtil util = SecurityUtil.Instance(); // 將驗證碼輸入到session中,用來驗證 String code = util.getString(); request.getSession().setAttribute("code", code); // 輸出打web頁面 try { ImageIO.write(util.getImage(), "jpg", response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } }
三,SecurityUtil代碼:session
package cc.royao.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; public class SecurityUtil { private BufferedImage image;// 圖像 private String str;// 驗證碼 private static char code[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789".toCharArray(); public static final String SESSION_CODE_NAME="code"; private SecurityUtil() { init();// 初始化屬性 } /* * 取得RandomNumUtil實例 */ public static SecurityUtil Instance() { return new SecurityUtil(); } /* * 取得驗證碼圖片 */ public BufferedImage getImage() { return this.image; } /* * 取得圖片的驗證碼 */ public String getString() { return this.str; } private void init() { // 在內存中建立圖象 int width = 85, height = 20; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 獲取圖形上下文 Graphics g = image.getGraphics(); // 生成隨機類 Random random = new Random(); // 設定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 設定字體 g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 隨機產生155條幹擾線,使圖象中的認證碼不易被其它程序探測到 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 155; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } // 取隨機產生的認證碼(4位數字) String sRand = ""; for (int i = 0; i < 4; i++) { String rand = String.valueOf(code[random.nextInt(code.length)]); sRand += rand; // 將認證碼顯示到圖象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); // 調用函數出來的顏色相同,多是由於種子太接近,因此只能直接生成 g.drawString(rand, 13 * i + 6, 16); } // 賦值驗證碼 this.str = sRand; // 圖象生效 g.dispose(); this.image = image;/* 賦值圖像 */ } /* * 給定範圍得到隨機顏色 */ private Color getRandColor(int fc, int bc) { Random random = new Random(); if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } }