探討Java驗證碼製作(上篇)_java

來源:互聯網
上載者:User

相信大家對驗證碼這玩意不會陌生,無論是申請帳號還是某些情況下登入時都會要求輸入驗證碼。經過統計,驗證碼一次驗證就成功通過的機率是90%,並不高,那麼很多人對於這種降低使用者體驗度的設計肯定會懷疑他的必要性,但黑格爾說過:凡是合乎理性的東西都是現實的;凡是現實的東西都是合乎理性的。接下來我們來瞭解一下驗證碼。

驗證碼是一種區別使用者是電腦還是人的公用全Bot,他被用於防止惡意破解密碼、刷票、論壇灌水,防止駭客通過暴力破解方式不斷地登入,應用於銀行、社區、論壇、投票系統等等。

廢話不多說我們來看看我已知的用Java實現驗證碼的四種方式。

方法一:

第一種方法是我最先想到的,也是實現邏輯最簡單的,但效率、安全性極其不高。

具體操作就是:1、用photoshop製作出驗證碼圖片,矩形圖片上可有必要的英文字母、數字或中文(如上)

2、將圖片顯示在swing控制項中或是jsp頁面中

3、在代碼中為每張圖片匹配上相應的驗證碼字串

4、在提交時擷取組件或文字框中的字串與每張圖片的字串用equals()方法進行比較

缺憾就是製作驗證碼圖片的過程太費時,實現方法極low,極不推薦這樣實現,下面的方法將越來越高效美觀相對安全。

方法二:

這裡講Java Web,Servlet下的驗證碼實現,實現起來邏輯還是很清晰的。

省去較簡單的實現代碼,我們先從前台關鍵代碼說起:

當我們點擊"看不清"時,驗證碼圖片會進行一個重新整理,會調用一個js函數用於重新設定圖片路徑來更換圖片,請看下面代碼,代碼中<%=request.getContextPath()%>是為瞭解決相對路徑的問題,可返回網站的根路徑,而/servlet/ImageServlet是一個整體,指向的就是ImageServlet這個servlet,為什麼要在之前加個/servlet呢,因為我們在web.xml中做了配置映射,可理解為換了個更長的名稱。接著看下面js函數,可能有些人會有疑問,為什麼擷取一個目前時間然後加在路徑最後呢,其實這是為瞭解決瀏覽器緩衝的問題,就是當觸發了ImageServlet後雖然驗證碼圖片換了但緩衝還沒變顯示出來的驗證碼圖片不變的問題,藉助每時每刻時間不同可以讓瀏覽器緩衝失效。

<script type="text/javascript">  function reloadCode(){   var time = new Date().getTime();   document.getElementById("imagecode").src="<%=request.getContextPath() %>/servlet/ImageServlet?d="+time;  } </script>

下面是web.xml中的關鍵配置資訊:

<script type="text/javascript"> function reloadCode(){  var time = new Date().getTime();  document.getElementById("imagecode").src="<%=request.getContextPath() %>/servlet/ImageServlet?d="+time; } </script>

然後我們看關鍵的ImageServlet是怎麼產生圖片的:

<servlet>  <servlet-name>ImageServlet</servlet-name>  <servlet-class>com.muke.ImageServlet</servlet-class> </servlet> <servlet>  <servlet-name>LoginServlet</servlet-name>  <servlet-class>com.muke.LoginServlet</servlet-class> </servlet> <servlet-mapping>  <servlet-name>ImageServlet</servlet-name>  <url-pattern>/servlet/ImageServlet</url-pattern> </servlet-mapping> <servlet-mapping>  <servlet-name>LoginServlet</servlet-name>  <url-pattern>/servlet/LoginServlet</url-pattern> </servlet-mapping> 

如果要更生動的描述這種驗證碼是怎麼樣來實現的,那麼就一個字“畫”,聽上去和第一種方法類似,還是比較low,但是用代碼來自動“畫”出驗證碼效率絕對翻了無數倍。我們來看上述代碼,首先執行個體化了一個BufferedImage對象bi,bi是用來畫出那張驗證碼圖片的,然後用bi得到一支畫筆g,用g畫出了實體的矩形背景,接著用簡單的邏輯通過畫筆g調用Java中常用的drawString()方法在矩形上畫出驗證碼字元,同時將字串依次加入StringBuffer可變字串對象中,最後存入jsp內建對象session中以便提交驗證碼後的比對,為了顯示出驗證碼,我們還需將產生驗證碼圖片以某種圖片格式寫入ImageIO流。

下面LoginServlet中可以看出,擷取剛剛ImageServlet存入session的字串就可以進行與驗證碼提交框中字串的比對了,可以把字串都變為小寫或大寫做一個忽略大小寫處理。

 public class ImageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{  BufferedImage bi = new BufferedImage(,,BufferedImage.TYPE_INT_RGB);  Graphics g = bi.getGraphics();  Color c = new Color(,,);  g.setColor(c);  g.fillRect(, , , );  char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();  Random r = new Random();  int len=ch.length,index;  StringBuffer sb = new StringBuffer();  for(int i=; i<; i++){  index = r.nextInt(len);  g.setColor(new Color(r.nextInt(),r.nextInt(),r.nextInt()));  g.drawString(ch[index]+"", (i*)+, );  sb.append(ch[index]);  }  request.getSession().setAttribute("piccode", sb.toString());  ImageIO.write(bi, "JPG", response.getOutputStream()); } }

下面是實現圖例:

以上所述是小編給大家介紹的Java驗證碼製作的相關知識,希望對大家有所協助!後續給大家介紹java驗證碼製作(下),感興趣的朋友敬請關注云棲社區網站!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.