Java Web(四) 一次性驗證碼的程式碼實現

一杯涼茶發表於2017-02-21

     其實實現程式碼的邏輯非常簡單,真的超級超級簡單。

     1、在登入頁面上login.jsp將驗證碼圖片使用標籤<img src="xxx">將繪製驗證碼圖片的url給它

     2、在伺服器端就兩個servlet,一個就是用來繪製驗證碼圖片的VerifyCodeServlet,另一個就是登入時驗證驗證碼是否點寫正確或是否重複提交的LoginServlet

     3、在VerifyCodeServlet中,將驗證碼的四個字母存入session中,然後在LoginServlet中,將請求中提交過來的驗證碼與session中的進行對比,如果正確,則驗證成功,並且將session中的驗證碼刪除,為什麼要刪除?保證session中的資料只能被用一次,防止重複提交資料,如果不正確,就使用request,將錯誤資訊儲存,然後請求轉發到登入頁面顯示錯誤資訊,如果發現session中的資料為null,說明重複提交了資料,也將錯誤資訊用同樣的方法返回到登入頁面。

     難點就在於:VerifyCodeServlet的程式碼實現.對繪圖的程式碼不是很熟悉。


login.jsp

 

  <body>
            <%
        String msg = (String)request.getAttribute("msg");
        if(msg != null){
            out.print(msg);
        }
    %>
    
    <form action="/test01/LoginServlet" method="post">
        使用者名稱:<input type="text" name="username" /> <br/>
        驗證碼:<input type="text" name="verifyCode" size="5" /> <img src="/test01/VerifyCodeServlet" /> <br/>
        <input type="submit" value="提交"/>
    </form> 
  </body>
View Code

 

 

VerifyCodeServlet.java

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

         //宣告驗證碼
        int width = 60;
        int height = 30;
        String data = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijklmnpqrstuvwxyz";    //隨機字元字典,其中0,o,1,I 等難辨別的字元最好不要
        Random random = new Random();//隨機類
        //1 建立圖片資料快取區域(核心類)
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//建立一個彩色的圖片
        //2 獲得畫板(圖片,ps圖層),繪畫物件。
        Graphics g = image.getGraphics();
        //3 選擇顏色,畫矩形3,4步是畫一個有內外邊框的效果
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, width, height);
        //4白色矩形
        g.setColor(Color.WHITE);
        g.fillRect(1, 1, width-2, height-2);
        
        /**1 提供快取區域,為了存放4個隨機字元,以便存入session */
        StringBuilder builder = new StringBuilder();
        
        //5 隨機生成4個字元
                    //設定字型顏色
        g.setFont(new Font("宋體", Font.BOLD&Font.ITALIC, 20));
        for(int i = 0 ; i < 4 ;i ++){
            //隨機顏色
            g.setColor(new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255)));
            
            //隨機字元
            int index = random.nextInt(data.length());
            String str = data.substring(index, index + 1);
            
            /**2 快取*/
            builder.append(str);
            
            //寫入
            g.drawString(str, (width / 6) * (i + 1) , 20);                     
        }
        //給圖中繪製噪音點,讓圖片不那麼好辨別
        for(int j=0,n=random.nextInt(100);j<n;j++){
            g.setColor(Color.RED);
            g.fillRect(random.nextInt(width),random.nextInt(height),1,1);//隨機噪音點
        }

        
        /**3 獲得隨機資料,並儲存session*/
        String tempStr = builder.toString();
        request.getSession().setAttribute("sessionCacheData",tempStr);
        
        
        //.. 生成圖片傳送到瀏覽器 --相當於下載
        ImageIO.write(image, "jpg", response.getOutputStream());
    }
View Code

 

 

LoginServlet.java

 

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1 獲得使用者輸入的驗證碼
        String verifyCode = request.getParameter("verifyCode");
        //2 獲得伺服器session 存放資料 ,如果沒有返回null
        String sessionCacheData = (String) request.getSession().getAttribute("sessionCacheData");
        // *將伺服器快取session資料移除
        request.getSession().removeAttribute("sessionCacheData");
        // ** 判斷伺服器是否存在
        if(sessionCacheData == null){
            request.setAttribute("msg", "請不要重複提交");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        }
        //3 比較
        if(! sessionCacheData.equalsIgnoreCase(verifyCode)){
            //使用者輸入錯誤
            // * 存放request作用域
            request.setAttribute("msg", "驗證碼輸入錯誤");
            // * 請求轉發
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            
            return;
        }
        
        //...... 登入操作

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

}
View Code

 

 

效果圖:

    

    驗證碼錯誤時:

      

注意:

    如果要拷貝程式碼的話,需要改就應該就是那幾處url,你的肯定跟我的不一樣,並且有些人設定的servlet的訪問路徑也不一樣,所以拷貝的話只需要拷貝關鍵程式碼即可。

 

 

  

相關文章