JAVA實現驗證碼

來源:互聯網
上載者:User

一、主要功能:

1、支援純數字、大寫字母、小寫字母,及兩兩混合或三者混合類型驗證碼;

2、支援自訂特殊字元排除(如0oOi1jI);

3、支援圖片及文字兩種類型驗證碼;

4、支援自訂驗證碼圖片大小;

5、支援自訂幹擾線條數;

6、支援自訂及隨機定義圖片、文字、幹擾線顏色;

其他:樣本頁面提供了<iframe>和<img>兩種頁面顯示驗證碼的方式。

a、僅阿拉伯數字

 

二、主要代碼

1.index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%

    String path = request.getContextPath();

    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

        <title><%=basePath%></title>

    </head>

  <script type="text/javascript">

    var req;

 

    //提交留言

    function pubMsg(){

        msgTitle   = document.msgForm.msgTitle.value;

        msgContent = document.msgForm.msgContent.value;

        verifyCode = document.msgForm.verifyCode.value;

     

        //檢查輸入內容格式

        if(msgTitle.length<5||msgContent.length<5){

            alert("標題和內容不能少於5個字元");

            return;

        }

        if(verifyCode.length==0){

          alert("請輸入驗證碼");

          return;

        }

   

        //獲得 XMLHttpRequest對象

        if(window.XMLHttpRequest)

            req=new XMLHttpRequest();

        else if(window.ActiveXObject)

            req=new ActiveXObject("Microsoft.XMLHTTP");

   

        //提交請求

        if(req){

          req.onreadystatechange=callBack;//指定伺服器響應結果處理函數(注意僅函數名無括弧)

          url="<%=path%>/servlet/PubMsgServlet?msgTitle="+msgTitle+"&msgContent="+msgContent+"&verifyCode="+verifyCode;

          req.open("GET",url,false);

          req.send();

      }

  }

 

  //伺服器響應結果處理函數

  function callBack(){

      if(req.readyState==4){

          if(req.status==200){

              next=req.responseText;//獲得伺服器處理結果

              if(next=="this"){

                  alert("驗證碼不正確,請重新輸入");

                  verifyCodeFrame.location.reload();//重新整理驗證碼

              }else{

                  document.msgForm.msgTitle.value="";

                  document.msgForm.msgContent.value="";

                  window.location=next;//跳轉頁面

              }

          }else{

              alert(req.status+":"+req.statusText);

          }

      }

      document.msgForm.verifyCode.value="";

  }

 

  //更換驗證碼

  function changeVerifyCode(){

      //1、如果用<iframe>實現,則重新載入<iframe>的內容

      //verifyCodeFrame.location.reload();

     

      //2、如果用<img>實現,則修改<img src=url>的url

      //這裡有一個小技巧,如果給url賦相同的值,瀏覽器不會重新發出請求,因此用js產生一個即時毫秒數做url中的參數

      t=new Date().getTime();

      document.msgForm.verifyCodeImg.src="<%=path%>/servlet/VerifyCodeServlet?t="+t;

  }

  </script>

<body>

  <form name="msgForm" action="" method="post">

    <table border=0>

        <tr>

            <td>標題:</td>

            <td><input name="msgTitle" size="65" /></td>

        </tr>

        <tr>

            <td>內容:</td>

            <td><textarea name="msgContent" rows="10" cols="64"></textarea></td>

        </tr>

        <tr>

            <td>驗證碼:</td>

            <td>

              <input name="verifyCode"  style="height: 29px; width =70px; font-size: 25px" />

              <!-- 以下:兩種顯示驗證碼的方式 -->

              <!-- 1、採用<iframe>實現 -->

              <!--

                  <iframe name="verifyCodeFrame" src="<%=path + "/servlet/VerifyCodeServlet"%>"

                width="100" height="30" frameborder=0 align="top" marginheight=0 marginwidth=0 scrolling=no></iframe>

                 -->

              <!-- 2、採用<img>實現 -->

              <img name="verifyCodeImg" src="<%=path%>/servlet/VerifyCodeServlet" style="cursor:hand" align="align" onClick="changeVerifyCode()" />

              <!-- 以上:兩種顯示驗證碼的方式 -->

              <font style="color: blue;"><a href="javascript:changeVerifyCode()">看不清?</a> </font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

              <input type="button" value=" 發表留言 " onClick="pubMsg()" />

          </td>

    </tr>

  </table>

</form>

</body>

</html>

 

 

2.org.javachina.util.VerifyCode.java

package org.javachina.util;

import java.util.Random;

import java.awt.image.BufferedImage;

import java.awt.Graphics;

import java.awt.Font;

import java.awt.Color;

/**

 * 驗證碼產生器類,可產生數字、大寫、小寫字母及三者混合類型的驗證碼。 支援自訂驗證碼字元數量; 支援自訂驗證碼圖片的大小; 支援自訂需排除的特殊字元;

 * 支援自訂幹擾線的數量; 支援自訂驗證碼圖文顏色

 *

 * @author org.javachina

 * @version 1.01

 */

public class VerifyCode {

    /**

     * 驗證碼類型為僅數字 0~9

     */

    public static final int TYPE_NUM_ONLY = 0;

    /**

     * 驗證碼類型為僅字母,即大寫、小寫字母混合

     */

    public static final int TYPE_LETTER_ONLY = 1;

    /**

     * 驗證碼類型為數字、大寫字母、小寫字母混合

     */

    public static final int TYPE_ALL_MIXED = 2;

    /**

     * 驗證碼類型為數字、大寫字母混合

     */

    public static final int TYPE_NUM_UPPER = 3;

    /**

     * 驗證碼類型為數字、小寫字母混合

     */

    public static final int TYPE_NUM_LOWER = 4;

    /**

     * 驗證碼類型為僅大寫字母

     */

    public static final int TYPE_UPPER_ONLY = 5;

    /**

     * 驗證碼類型為僅小寫字母

     */

    public static final int TYPE_LOWER_ONLY = 6;

    private VerifyCode() {

    }

    /**

     * 產生驗證碼字串

     *

     * @param type

     *            驗證碼類型,參見本類的靜態屬性

     * @param length

     *            驗證碼長度,大於0的整數

     * @param exChars

     *            需排除的特殊字元(僅對數字、字母混合型驗證碼有效,無需排除則為 null)

     * @return 驗證碼字串

     */

    public static String generateTextCode(int type, int length, String exChars) {

        if (length <= 0)

            return "";

        StringBuffer code = new StringBuffer();

        int i = 0;

        Random r = new Random();

        switch (type) {

        // 僅數字

        case TYPE_NUM_ONLY:

            while (i < length) {

                int t = r.nextInt(10);

                if (exChars == null || exChars.indexOf(t + "") < 0) {// 排除特殊字元

                    code.append(t);

                    i++;

                }

            }

            break;

        // 僅字母(即大寫字母、小寫字母混合)

        case TYPE_LETTER_ONLY:

            while (i < length) {

                int t = r.nextInt(123);

                if ((t >= 97 || (t >= 65 && t <= 90)) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        // 數字、大寫字母、小寫字母混合

        case TYPE_ALL_MIXED:

            while (i < length) {

                int t = r.nextInt(123);

                if ((t >= 97 || (t >= 65 && t <= 90) || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        // 數字、大寫字母混合

        case TYPE_NUM_UPPER:

            while (i < length) {

                int t = r.nextInt(91);

                if ((t >= 65 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        // 數字、小寫字母混合

        case TYPE_NUM_LOWER:

            while (i < length) {

                int t = r.nextInt(123);

                if ((t >= 97 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        // 僅大寫字母

        case TYPE_UPPER_ONLY:

            while (i < length) {

                int t = r.nextInt(91);

                if ((t >= 65) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        // 僅小寫字母

        case TYPE_LOWER_ONLY:

            while (i < length) {

                int t = r.nextInt(123);

                if ((t >= 97) && (exChars == null || exChars.indexOf((char) t) < 0)) {

                    code.append((char) t);

                    i++;

                }

            }

            break;

        }

        return code.toString();

    }

    /**

     * 已有驗證碼,產生驗證碼圖片

     *

     * @param textCode

     *            文本驗證碼

     * @param width

     *            圖片寬度

     * @param height

     *            圖片高度

     * @param interLine

     *            圖片中幹擾線的條數

     * @param randomLocation

     *            每個字元的高低位置是否隨機

     * @param backColor

     *            圖片顏色,若為null,則採用隨機顏色

     * @param foreColor

     *            字型顏色,若為null,則採用隨機顏色

     * @param lineColor

     *            幹擾線顏色,若為null,則採用隨機顏色

     * @return 圖片緩衝對象

     */

    public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor,

            Color foreColor, Color lineColor) {

        BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = bim.getGraphics();

        // 畫背景圖

        g.setColor(backColor == null ? getRandomColor() : backColor);

        g.fillRect(0, 0, width, height);

        // 畫幹擾線

        Random r = new Random();

        if (interLine > 0) {

            int x = 0, y = 0, x1 = width, y1 = 0;

            for (int i = 0; i < interLine; i++) {

                g.setColor(lineColor == null ? getRandomColor() : lineColor);

                y = r.nextInt(height);

                y1 = r.nextInt(height);

                g.drawLine(x, y, x1, y1);

            }

        }

        // 寫驗證碼

        // g.setColor(getRandomColor());

        // g.setColor(isSimpleColor?Color.BLACK:Color.WHITE);

        // 字型大小為圖片高度的80%

        int fsize = (int) (height * 0.8);

        int fx = height - fsize;

        int fy = fsize;

        g.setFont(new Font(Font.DIALOG, Font.PLAIN, fsize));

        // 寫驗證碼字元

        for (int i = 0; i < textCode.length(); i++) {

            fy = randomLocation ? (int) ((Math.random() * 0.3 + 0.6) * height) : fy;// 每個字元高低是否隨機

            g.setColor(foreColor == null ? getRandomColor() : foreColor);

            g.drawString(textCode.charAt(i) + "", fx, fy);

            fx += fsize * 0.9;

        }

        g.dispose();

        return bim;

    }

    /**

     * 產生圖片驗證碼

     *

     * @param type

     *            驗證碼類型,參見本類的靜態屬性

     * @param length

     *            驗證碼字元長度,大於0的整數

     * @param exChars

     *            需排除的特殊字元

     * @param width

     *            圖片寬度

     * @param height

     *            圖片高度

     * @param interLine

     *            圖片中幹擾線的條數

     * @param randomLocation

     *            每個字元的高低位置是否隨機

     * @param backColor

     *            圖片顏色,若為null,則採用隨機顏色

     * @param foreColor

     *            字型顏色,若為null,則採用隨機顏色

     * @param lineColor

     *            幹擾線顏色,若為null,則採用隨機顏色

     * @return 圖片緩衝對象

     */

    public static BufferedImage generateImageCode(int type, int length, String exChars, int width, int height, int interLine, boolean randomLocation,

            Color backColor, Color foreColor, Color lineColor) {

        String textCode = generateTextCode(type, length, exChars);

        BufferedImage bim = generateImageCode(textCode, width, height, interLine, randomLocation, backColor, foreColor, lineColor);

        return bim;

    }

    /**

     * 產生隨機顏色

     *

     * @return

     */

    private static Color getRandomColor() {

        Random r = new Random();

        Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));

        return c;

    }

    public static void main(String[] args) {

    }

}

 

 

3.org.javachina.servlet.VerifyCodeServlet.java

package org.javachina.servlet;

import java.awt.Color;

import java.awt.image.BufferedImage;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.javachina.util.VerifyCode;

public class VerifyCodeServlet extends HttpServlet {

    public VerifyCodeServlet() {

        super();

    }

    public void destroy() {

        super.destroy();

    }

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

        // 設定瀏覽器不緩衝本頁

        response.setHeader("Cache-Control", "no-cache");

        // 產生驗證碼,寫入使用者session

        String verifyCode = VerifyCode.generateTextCode(VerifyCode.TYPE_UPPER_ONLY, 4, null);

        request.getSession().setAttribute("verifyCode", verifyCode);

        // 輸出驗證碼給用戶端

        response.setContentType("image/jpeg");

        BufferedImage bim = VerifyCode.generateImageCode(verifyCode, 60, 20, 3, true, Color.WHITE, Color.BLACK, null);

        ImageIO.write(bim, "JPEG", response.getOutputStream());

    }

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

    }

    public void init() throws ServletException {

    }

}

 

 

4.org.javachina.servlet.PubMsgServlet.java

package org.javachina.servlet;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class PubMsgServlet extends HttpServlet {

    public PubMsgServlet() {

        super();

    }

    public void destroy() {

        super.destroy(); // Just puts "destroy" string in log

        // Put your code here

    }

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

        // 得到留言標題、內容及使用者輸入的驗證碼

        String msgTitle   = request.getParameter("msgTitle");

        String msgContent = request.getParameter("msgContent");

        String verifyCode = request.getParameter("verifyCode");

        // 取session中的正確驗證碼

        String legalCode = null;

        if (request.getSession().getAttribute("verifyCode") != null)

            legalCode = (String) (request.getSession().getAttribute("verifyCode"));

        String next;

        // 比較session中的驗證碼與使用者輸入是否一致(這裡忽略了大小寫)

        if (verifyCode != null && verifyCode.equalsIgnoreCase(legalCode)) {

            /*

             * 儲存留言內容(省略)

             */

            // 指定下一個URL

            next = request.getContextPath() + "/ok.jsp";

        } else

            next = "this";

        response.setContentType("text/plain");

        PrintWriter out = response.getWriter();

        out.print(next);

        out.flush();

        out.close();

    }

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

    }

    public void init() throws ServletException {

    }

}

 

5. ok.jsp

  <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

   <html>

    <body>

            您的留言已提交!<input type="button" value=" OK " onClick="window.history.go(-1)"/><br>

    </body>

    </html>



6.修改web.xml   添加如下內容:

  <servlet>

    <servlet-name>VerifyCodeServlet</servlet-name>

    <servlet-class>org.javachina.servlet.VerifyCodeServlet</servlet-class>

  </servlet>

  <servlet>

    <servlet-name>PubMsgServlet</servlet-name>

    <servlet-class>org.javachina.servlet.PubMsgServlet</servlet-class>

  </servlet>

  <servlet-mapping>

    <servlet-name>VerifyCodeServlet</servlet-name>

    <url-pattern>/servlet/VerifyCodeServlet</url-pattern>

  </servlet-mapping>

  <servlet-mapping>

    <servlet-name>PubMsgServlet</servlet-name>

    <url-pattern>/servlet/PubMsgServlet</url-pattern>

  </servlet-mapping>

 

 

轉載地址:  http://www.java3z.com/cwbwebhome/article/article3/3468.html?id=2132

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.