您好,登錄后才能下訂單哦!
本文實例為大家分享了springmvc實現驗證碼功能展示的具體代碼,供大家參考,具體內容如下
先看效果圖:
思路:
首先驗證碼是一張圖片,是一張有著隨機字母、數字、圖案等組成的圖片,所以這圖片肯定不是固定不變的,肯定是由后端隨機制造出來的,前端用img的src去不斷訪問這個制造的方法。
第一步:前端頁面編寫
登錄使用的是ajax方法,所以使用的是調用點擊事件進行,驗證碼的圖片放在a標簽中是為了方便點擊變換驗證碼。顯示圖片用的是img的src屬性,因為使用的是spingmvc所以調用后臺方法使用action的方式。
<form> <div id="login_tip"> 管理員登錄 </div> <div><input type="text" id="user_code" name="user_code" class="username" placeholder="請輸入賬號"></div> <div><input type="password" id="user_account" name="user_account" class="pwd" placeholder="請輸入密碼"></div> <div id="btn_area"> <input type="text" id="VerificationCode" name="VerificationCode" placeholder="請輸入驗證碼" class="verify"> <a href="javascript:void(0);" rel="external nofollow" onclick="VerificationCode()"> <img id="randCodeImage" alt="驗證碼" src="VerificationCode/generate.action" width="100" height="40"/> </a> </div> <div > <input type="button" name="button" id="sub_btn" onclick="login()" value="登錄"/> </div> <div id="verification_Code"><b></b></div> </form>
第二步:編寫JS代碼
因為登錄采用的是ajxa,所以后臺登錄會驗證一些數據,不正確的會返回數據到登錄頁面。這里說明一下,在調用生成驗證碼的方法后面為什么要加一個隨機數,這里的隨機數以及這個隨機數的參數名稱可以隨意寫,后端不做任何操作的,這里是防止瀏覽器對一個相同方法進行調用時取緩存的方法,而點擊圖片或驗證碼輸入錯誤不會自動刷新而改變圖片的問題做處理。
<script type="text/javascript"> function login(){ //這是使用ajax的方式提交 $.ajax({ type:'post', url:'Uase/query.action', //data:$('#loginInputForm').serialize(), data:{ 'user_code' : $("#user_code").val(), 'user_account' :$("#user_account").val(), 'VerificationCode':$("#VerificationCode").val(), }, dataType:'json', success:function(obj){ var rad = Math.floor(Math.random() * Math.pow(10, 8)); if(obj && obj.success=='true'){ window.location.href='Uase/login.action'; }else{ document.getElementById("verification_Code"). innerHTML =obj.msg; //uuuy是隨便寫的一個參數名稱,后端不會做處理,作用是避免瀏覽器讀取緩存的鏈接 $("#randCodeImage").attr("src", "VerificationCode/generate.action?uuuy="+rad); $("#VerificationCode").val("").focus(); // 清空并獲得焦點 } } }); } /** *驗證碼刷新 */ function VerificationCode(){ var rad = Math.floor(Math.random() * Math.pow(10, 8)); //uuuy是隨便寫的一個參數名稱,后端不會做處理,作用是避免瀏覽器讀取緩存的鏈接 $("#randCodeImage").attr("src", "VerificationCode/generate.action?uuuy="+rad); } </script>
第三步:編寫后臺Controller控制類
主方法為VerificationCode,里面會用到一些隨機數生產的方法以及一些輔助類,全用用上就可以了,因為我這里用到了可以更改類型的驗證碼,所以用到了一個自己編寫的公共的工具類。
@RequestMapping("/VerificationCode") public class VerificationCodeController extends HttpServlet{ private static final long serialVersionUID = 1L; /** * 這里用作存入session的名稱 */ private static final String SESSION_KEY_OF_RAND_CODE = "randCode"; // todo 要統一常量 /** * */ private static final int count = 200; /** * 定義圖形大小(寬) */ private static final int width = 105; /** * 定義圖形大小(高) */ private static final int height = 35; /** * 干擾線的長度=1.414*lineWidth */ private static final int lineWidth = 1; @RequestMapping(value = "/generate", method = { RequestMethod.POST, RequestMethod.GET }) public void VerificationCode( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設置頁面不緩存 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // response.setContentType("image/png"); // 在內存中創建圖象 final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 獲取圖形上下文 final Graphics2D graphics = (Graphics2D) image.getGraphics(); // 設定背景顏色 graphics.setColor(Color.WHITE); // ---1.Color.WHITE為白色 graphics.fillRect(0, 0, width, height);//填充衍射 // 設定邊框顏色 //graphics.setColor(getRandColor(100, 200)); // ---2.這是以數字型來設置顏色,顏色模式是指使用三種基色:紅、綠、藍,通過三種顏色的調整得出其它各種顏色,這三種基色的值范圍為0~255 graphics.drawRect(0, 0, width - 1, height - 1); final Random random = new Random(); // 隨機產生干擾線,使圖象中的認證碼不易被其它程序探測到 for (int i = 0; i < count; i++) { graphics.setColor(getRandColor(150, 200)); // ---3. final int x = random.nextInt(width - lineWidth - 1) + 1; // 保證畫在邊框之內 final int y = random.nextInt(height - lineWidth - 1) + 1; final int xl = random.nextInt(lineWidth); final int yl = random.nextInt(lineWidth); graphics.drawLine(x, y, x + xl, y + yl); } // 取隨機產生的認證碼(4位數字) final String resultCode = exctractRandCode(); for (int i = 0; i < resultCode.length(); i++) { // 將認證碼顯示到圖象中,調用函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成 // graphics.setColor(new Color(20 + random.nextInt(130), 20 + random // .nextInt(130), 20 + random.nextInt(130))); // 設置字體顏色 graphics.setColor(Color.BLACK); // 設置字體樣式 //graphics.setFont(new Font("Arial Black", Font.ITALIC, 18)); graphics.setFont(new Font("Times New Roman", Font.BOLD, 24)); // 設置字符,字符間距,上邊距 System.out.print(resultCode.charAt(i)); graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26); } System.out.println("直接輸出:"+resultCode); // 將認證碼存入SESSION request.getSession().setAttribute(SESSION_KEY_OF_RAND_CODE, resultCode); // 圖象生效 graphics.dispose(); // 輸出圖象到頁面 ImageIO.write(image, "JPEG", response.getOutputStream()); } /** * @return 隨機碼 */ private String exctractRandCode() { final String randCodeType = ResourceUtil.getRandCodeType(); int randCodeLength = Integer.parseInt(ResourceUtil.getRandCodeLength()); if (randCodeType == null) { return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength); } else { switch (randCodeType.charAt(0)) { case '1': return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength); case '2': return RandCodeImageEnum.LOWER_CHAR.generateStr(randCodeLength); case '3': return RandCodeImageEnum.UPPER_CHAR.generateStr(randCodeLength); case '4': return RandCodeImageEnum.LETTER_CHAR.generateStr(randCodeLength); case '5': return RandCodeImageEnum.ALL_CHAR.generateStr(randCodeLength); default: return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength); } } } /** * 描述:根據給定的數字生成不同的顏色 * @param 這是以數字型來設置顏色,顏色模式是指使用三種基色:紅、綠、藍,通過三種顏色的調整得出其它各種顏色,這三種基色的值范圍為0~255 * @param 這是以數字型來設置顏色,顏色模式是指使用三種基色:紅、綠、藍,通過三種顏色的調整得出其它各種顏色,這三種基色的值范圍為0~255 * @return 描述:返回顏色 */ private Color getRandColor(int fc, int bc) { // 取得給定范圍隨機顏色 final Random random = new Random(); if (fc > 255) { fc = 255; } if (bc > 255) { bc = 255; } final int r = fc + random.nextInt(bc - fc); final int g = fc + random.nextInt(bc - fc); final int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } /** * 驗證碼輔助類 */ enum RandCodeImageEnum { /** * 混合字符串 */ ALL_CHAR("0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), // 去除小寫的l和o這個兩個不容易區分的字符; /** * 字符 */ LETTER_CHAR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), /** * 小寫字母 */ LOWER_CHAR("abcdefghijklmnopqrstuvwxyz"), /** * 數字 */ NUMBER_CHAR("0123456789"), /** * 大寫字符 */ UPPER_CHAR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); /** * 待生成的字符串 */ private String charStr; /** * @param charStr */ private RandCodeImageEnum(final String charStr) { this.charStr = charStr; } /** * 生產隨機驗證碼 * * @param codeLength * 驗證碼的長度 * @return 驗證碼 */ public String generateStr(final int codeLength) { final StringBuffer sb = new StringBuffer(); final Random random = new Random(); final String sourseStr = getCharStr(); for (int i = 0; i < codeLength; i++) { sb.append(sourseStr.charAt(random.nextInt(sourseStr.length()))); } return sb.toString(); } /** * @return the {@link #charStr} */ public String getCharStr() { return charStr; } } }
第四步:編寫公用的工具類
/** * 項目參數工具類 * */ public class ResourceUtil { private static final ResourceBundle bundle = java.util.ResourceBundle.getBundle("sysConfig"); /** * 獲取隨機碼的長度 * * @return 隨機碼的長度 */ public static String getRandCodeLength() { return bundle.getString("randCodeLength"); } /** * 獲取隨機碼的類型 * * @return 隨機碼的類型 */ public static String getRandCodeType() { return bundle.getString("randCodeType"); } }
第五步:配置sysConfig.properties
randCodeLength=4 randCodeType=5
第六步:到這里就大功告成了,可以試試效果了
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。