Web開發中的驗證碼圖片的生成-基於Java的實現

     你們在使用Web網站的時候,常常會發現有個驗證碼須要輸入,這裏驗證碼用來作什麼事情呢?其實很簡單,驗證碼圖片的做用是讓用戶經過肉眼來觀察圖片,把圖片中的內容填寫到輸入框中,在登陸的時候,若是驗證碼內容輸入不正確,就算你的登陸用戶名和密碼都正確也不行,這樣能夠很好的防治有人用程序不停的猜想別人的賬號和密碼,由於程序難以從一個圖片中提取驗證碼的內容,從而難以使用程序來進行重複猜想,這樣只是憑人工的辦法,是很難在短期內猜出賬號和密碼的。因此驗證碼圖片實際是爲了保護用戶的權益。那麼到底如何在web開發中使用驗證碼圖片呢?
    
html

     驗證碼圖片是由程序動態產生的,每次訪問的內容都是隨機的。那麼如何採用程序動態產生圖片,並可以顯示在客戶端頁面中呢?原理很簡單,對於java而言,咱們首先開發一個Servlet,這個Servlet的任務就是給客戶端產生一個驗證碼圖片的輸入,示例代碼以下:java

  
  
  
  
  1. package com.web.servlet; 
  2. import java.awt.Color; 
  3. import java.awt.Graphics; 
  4. import java.awt.p_w_picpath.BufferedImage; 
  5. import java.io.IOException; 
  6. import javax.servlet.ServletException; 
  7. import javax.servlet.ServletOutputStream; 
  8. import javax.servlet.http.HttpServletRequest; 
  9. import javax.servlet.http.HttpServletResponse; 
  10. import com.sun.p_w_picpath.codec.jpeg.JPEGCodec; 
  11. import com.sun.p_w_picpath.codec.jpeg.JPEGImageEncoder; 
  12. public class ValidateImgServlet extends javax.servlet.http.HttpServlet implements 
  13. javax.servlet.Servlet { 
  14.     private static final long serialVersionUID = 1L
  15.  
  16.     protected void doGet(HttpServletRequest request, HttpServletResponse response) 
  17. throws ServletException, IOException { 
  18.         response.setContentType("p_w_picpath/jpeg"); 
  19.         
  20.         //產生四位驗證碼 
  21.         StringBuffer sb = new StringBuffer(4); 
  22.         for(int i=0; i<4; i++) { 
  23.             int n = (int)(Math.random() * 10); 
  24.             sb.append(n); 
  25.         } 
  26.         String validateCode = sb.toString(); 
  27.         //將驗證碼記錄在session中,便於用戶輸入以後的驗證 
  28.         request.getSession().setAttribute("ValidateCode", validateCode); 
  29.         
  30.         //建立緩存圖片 
  31.         BufferedImage p_w_picpath = new BufferedImage(80, 25, BufferedImage.TYPE_INT_RGB); 
  32.         Graphics g = p_w_picpath.getGraphics(); 
  33.                     
  34.         g.setColor(Color.LIGHT_GRAY); 
  35.         g.fillRect(0, 0, 80, 25); 
  36.         g.setColor(Color.BLACK); 
  37.         g.drawString(validateCode, 10, 20); 
  38.         g.dispose(); 
  39.         ServletOutputStream outStream = response.getOutputStream(); 
  40.         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream); 
  41.         encoder.encode(p_w_picpath); 
  42.         outStream.close(); 
  43.     }                      

在web.xml中對這個Servlet進行配置,配置信息以下:web

  
  
  
  
  1. <servlet> 
  2.         <description></description> 
  3.         <display-name>ValidateImgServlet</display-name> 
  4.         <servlet-name>ValidateImgServlet</servlet-name> 
  5.         <servlet-class>com.web.servlet.ValidateImgServlet</servlet-class> 
  6.     </servlet> 
  7.     <servlet-mapping> 
  8.         <servlet-name>ValidateImgServlet</servlet-name> 
  9.         <url-pattern>/validateimg.jpg</url-pattern> 
  10.     </servlet-mapping> 

好了,如今咱們能夠在登陸頁面中使用這個動態的驗證碼圖片了,login.jsp頁面內容以下:
數組

  
  
  
  
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.     pageEncoding="UTF-8"%> 
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/
  4. loose.dtd"> 
  5. <html> 
  6. <head> 
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  8. <title>Insert title here</title> 
  9. </head> 
  10. <body> 
  11.     請輸入登陸信息:<br /> 
  12.     <form name="login_form" method="post" action="login.action"> 
  13.     用戶名稱:<input type="text" name="username" /><br /> 
  14.     用戶密碼:<input type="password" name="password" /><br /> 
  15.     驗證碼:<input type="text" name="validatecode" /><img src="validateimg.jpg" border="0" />
  16. <br /> 
  17.     <input type="submit" value="登陸" /> 
  18.     </form> 
  19. </body> 
  20. </html> 

到這裏,若是你在web容器中運行這個jsp,你將會在瀏覽器中看見一個帶有驗證碼圖片的登陸表單,後續的驗證任務就交給你了。祝你好運!
瀏覽器

可是這個 驗證碼不是很美觀,徹底有理由弄得更真實些。修改代碼:緩存

  
  
  
  
  1. package com.servlet; 
  2.  
  3. import java.awt.Color; 
  4. import java.awt.Font; 
  5. import java.awt.Graphics2D; 
  6. import java.awt.p_w_picpath.BufferedImage; 
  7. import java.util.Random; 
  8. import javax.p_w_picpathio.ImageIO; 
  9. import javax.servlet.ServletException; 
  10. import javax.servlet.ServletOutputStream; 
  11. import javax.servlet.http.HttpServlet; 
  12. import javax.servlet.http.HttpServletRequest; 
  13. import javax.servlet.http.HttpServletResponse; 
  14. import javax.servlet.http.HttpSession; 
  15.  
  16. /** 
  17.  * 生成隨機驗證碼 
  18.  *  
  19.  * @author bitiliu 
  20.  *  
  21.  */ 
  22. public class ValidateCodeServlet extends HttpServlet { 
  23.     private static final long serialVersionUID = 1L
  24.     // 驗證碼圖片的寬度。 
  25.     private int width = 160
  26.     // 驗證碼圖片的高度。 
  27.     private int height = 20
  28.     // 驗證碼字符個數 
  29.     private int codeCount = 4
  30.  
  31.     private int x = 0
  32.     // 字體高度 
  33.     private int fontHeight; 
  34.     private int codeY; 
  35.     char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
  36.             'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 
  37.             'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 
  38.  
  39.     /** 
  40.      * 初始化驗證圖片屬性 
  41.      */ 
  42.     public void init() throws ServletException { 
  43.         // 從web.xml中獲取初始信息 
  44.         // 寬度 
  45.         String strWidth = this.getInitParameter("width"); 
  46.         // 高度 
  47.         String strHeight = this.getInitParameter("height"); 
  48.         // 字符個數 
  49.         String strCodeCount = this.getInitParameter("codeCount"); 
  50.         // 將配置的信息轉換成數值 
  51.         try { 
  52.             if (strWidth != null && strWidth.length() != 0) { 
  53.                 width = Integer.parseInt(strWidth); 
  54.             } 
  55.             if (strHeight != null && strHeight.length() != 0) { 
  56.                 height = Integer.parseInt(strHeight); 
  57.             } 
  58.             if (strCodeCount != null && strCodeCount.length() != 0) { 
  59.                 codeCount = Integer.parseInt(strCodeCount); 
  60.             } 
  61.         } catch (NumberFormatException e) { 
  62.         } 
  63.         x = width / (codeCount + 1); 
  64.         fontHeight = height - 2; 
  65.         codeY = height - 4; 
  66.     } 
  67.  
  68.     protected void service(HttpServletRequest req, HttpServletResponse resp) 
  69.             throws ServletException, java.io.IOException { 
  70.         // 定義圖像buffer 
  71.         BufferedImage buffImg = new BufferedImage(width, height, 
  72.                 BufferedImage.TYPE_INT_RGB); 
  73.         Graphics2D g = buffImg.createGraphics(); 
  74.         // 建立一個隨機數生成器類 
  75.         Random random = new Random(); 
  76.         // 將圖像填充爲白色 
  77.         g.setColor(Color.WHITE); 
  78.         g.fillRect(0, 0, width, height); 
  79.         // 建立字體,字體的大小應該根據圖片的高度來定。 
  80.         Font font = new Font("Fixedsys", Font.PLAIN, fontHeight); 
  81.         // 設置字體。 
  82.         g.setFont(font); 
  83.         // 畫邊框。 
  84.         g.setColor(Color.BLACK); 
  85.         g.drawRect(0, 0, width - 1, height - 1); 
  86.         // 隨機產生160條幹擾線,使圖象中的認證碼不易被其它程序探測到。 
  87.         g.setColor(Color.BLACK); 
  88.         for (int i = 0; i < 160; i++) { 
  89.             int x = random.nextInt(width); 
  90.             int y = random.nextInt(height); 
  91.             int xl = random.nextInt(12); 
  92.             int yl = random.nextInt(12); 
  93.             g.drawLine(x, y, x + xl, y + yl); 
  94.         } 
  95.         // randomCode用於保存隨機產生的驗證碼,以便用戶登陸後進行驗證。 
  96.         StringBuffer randomCode = new StringBuffer(); 
  97.         int red = 0green = 0blue = 0
  98.         // 隨機產生codeCount數字的驗證碼。 
  99.         for (int i = 0; i < codeCount; i++) { 
  100.             // 獲得隨機產生的驗證碼數字。 
  101.             String strRand = String.valueOf(codeSequence[random.nextInt(36)]); 
  102.             // 產生隨機的顏色份量來構造顏色值,這樣輸出的每位數字的顏色值都將不一樣。 
  103.             red = random.nextInt(255); 
  104.             green = random.nextInt(255); 
  105.             blue = random.nextInt(255); 
  106.             // 用隨機產生的顏色將驗證碼繪製到圖像中。 
  107.             g.setColor(new Color(red, green, blue)); 
  108.             g.drawString(strRand, (i + 1) * x, codeY); 
  109.             // 將產生的四個隨機數組合在一塊兒。 
  110.             randomCode.append(strRand); 
  111.         } 
  112.         // 將四位數字的驗證碼保存到Session中。 
  113.         HttpSession session = req.getSession(); 
  114.         session.setAttribute("validateCode", randomCode.toString()); 
  115.         // 禁止圖像緩存。 
  116.         resp.setHeader("Pragma", "no-cache"); 
  117.         resp.setHeader("Cache-Control", "no-cache"); 
  118.         resp.setDateHeader("Expires", 0); 
  119.         resp.setContentType("p_w_picpath/jpeg"); 
  120.         // 將圖像輸出到Servlet輸出流中。 
  121.         ServletOutputStream sos = resp.getOutputStream(); 
  122.         ImageIO.write(buffImg, "jpeg", sos); 
  123.         sos.close(); 
  124.     } 

web.xml 內容爲:session

 app

   
   
   
   
  1. <body> 
  2.     請輸入登陸信息:<br /> 
  3.     <form name="login_form" method="post" action="login.action"> 
  4.     用戶名稱:<input type="text" name="username" /><br /> 
  5.     用戶密碼:<input type="password" name="password" /><br /> 
  6.     驗證碼:<input type="text" name="validatecode" /><img src="validateCodeServlet" 
  7. border="0" /><br /> 
  8.     <input type="submit" value="登陸" /> 
  9.     </form> 
  10. </body> 

相關文章
相關標籤/搜索