Java實(shí)現(xiàn)驗(yàn)證碼制作

Java實(shí)現(xiàn)驗(yàn)證碼制作


java.jpg

第一章 概述

1.1 驗(yàn)證碼概述

  • 為什么要使用驗(yàn)證碼
  • 什么是驗(yàn)證碼
  • 使用Servlet實(shí)現(xiàn)驗(yàn)證碼
  • 使用開源組件實(shí)現(xiàn)驗(yàn)證碼
  • 驗(yàn)證碼的發(fā)展

如圖可以發(fā)現(xiàn)計(jì)算機(jī)也可以通過(guò)傳遞URL參數(shù)等來(lái)執(zhí)行登錄操作

沒有驗(yàn)證碼帶來(lái)的問題

  • 對(duì)特定用戶不斷登錄破解密碼
  • 對(duì)某個(gè)網(wǎng)站創(chuàng)建賬戶
  • 對(duì)某個(gè)網(wǎng)站提交垃圾數(shù)據(jù)
  • 對(duì)某個(gè)網(wǎng)站刷票

我們要通過(guò)驗(yàn)證碼, 由用戶肉眼識(shí)別其中的驗(yàn)證碼信息, 從而區(qū)分用戶是人還是計(jì)算機(jī)

驗(yàn)證碼的定義

  • 驗(yàn)證碼(captcha):是一種區(qū)分用戶是人還是計(jì)算機(jī)的公共全自動(dòng)程序.
  • 作用:可以防止惡意破解密碼,刷票,論壇灌水,有效防止某個(gè)黑客對(duì)某一個(gè)特定注冊(cè)用戶用特定程序暴力破解方式進(jìn)行不斷的登錄嘗試.
  • 實(shí)際上用驗(yàn)證碼是現(xiàn)在很多網(wǎng)站通行的方法,我們利用比較簡(jiǎn)易的方式實(shí)現(xiàn)了這個(gè)功能.

第二章 使用Servlert實(shí)現(xiàn)驗(yàn)證碼

2.1 使用Servlert實(shí)現(xiàn)驗(yàn)證碼的步驟

驗(yàn)證碼包含兩部分:

  1. 輸入框
  2. 顯示驗(yàn)證碼的圖片
    那么驗(yàn)證碼圖片是如何獲取的?

網(wǎng)頁(yè)顯示驗(yàn)證碼

  • <input type="text" id="verifyCode" name="verifyCode" size=6"" />
  • <img alt="驗(yàn)證碼" id="safecode" src=<%=request.getContextPath()%>/servlet/ImageServlet">

生成圖片

  • 生成圖片用到的類
  1. BufferedImage圖像數(shù)據(jù)緩沖區(qū)
  2. Graphics繪制圖片
  3. Color獲取顏色
  4. Random生成隨機(jī)數(shù)
  5. ImageIO輸出圖片

生成圖片的實(shí)現(xiàn)類

  • ImageServlet類
  1. 定義BufferedImage對(duì)象
  2. 獲得Graphics對(duì)象
  3. 通過(guò)Random產(chǎn)生隨機(jī)驗(yàn)證碼信息
  4. 使用Graphics繪制圖片
  5. 記錄驗(yàn)證碼信息到session中
  6. 使用ImageIO輸出圖片

校驗(yàn)驗(yàn)證碼是否正確

  • LoginServlet類
  1. 獲取頁(yè)面驗(yàn)證碼
  2. 獲取session保存的驗(yàn)證碼
  3. 比較驗(yàn)證碼
  4. 返回校驗(yàn)結(jié)果

使用Servlet實(shí)現(xiàn)驗(yàn)證碼流程


2.2 驗(yàn)證碼的代碼實(shí)現(xiàn)

    // /servlet/ImageServlet
    protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);
        Graphics gs = bi.getGraphics();
        Color c = new Color(196, 162, 129);
        gs.setColor(c);
        gs.fillRect(0,0,68,22);

        char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
        Random ran = new Random();
        int len = ch.length,index;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            index = ran.nextInt(len);
            gs.setColor(new Color(Test.getCorrectColor(196),Test.getCorrectColor(162),Test.getCorrectColor(129)));
            gs.drawString(ch[index] + "", (15 * i) + 8, 18);
            sb.append(ch[index]);
        }
        request.getSession().setAttribute("piccode", sb.toString());
        ImageIO.write(bi, "JPG", response.getOutputStream());
    }
    
    //Test.java
    public static int getCorrectColor(int a){
        Random ran = new Random();
        int temp = ran.nextInt(256);
        if (0 <= a - temp && a - temp < 40) {
            temp = a - 40;
        }
        if (a - temp < 0 && temp - a < 40) {
            temp = a + 40;
        }
        return temp;
    }

index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>驗(yàn)證碼制作</title>
      <script type="text/javascript">
          function flush_() {
              document.getElementById("captcha").src = "<%=request.getContextPath()%>/servlet/ImageServlet?d="+new Date();
              alert("88");
          }
      </script>
    </head>
    <body>
    驗(yàn)證碼: <input type="text" name="captcha" />
    <img alt="captcha" id="captcha" src="<%=request.getContextPath()%>/servlet/ImageServlet" />
    <a href="javascript:
    (function(){document.getElementById('captcha').src='<%=request.getContextPath()%>/servlet/ImageServlet?d='+new Date();})();">看不清楚</a>
    </body>
    </html>
    <%--這里提供了兩種js函數(shù)定義方法, 其中匿名函數(shù)的定義方式與java并不相同.
    這里采用的是(function(a){...})(a)這種格式.前一個(gè)()為方法體的定義, 后一個(gè)()表示傳參并執(zhí)行.
    匿名函數(shù)的缺點(diǎn)在與對(duì)一些需要重新解除函數(shù)綁定的事件類動(dòng)作無(wú)法解綁?個(gè)人理解, 并不懂.
    同時(shí), 在方法體中由于不能使用""進(jìn)行書寫, 則選擇使用''代替, 或者使用"字符轉(zhuǎn)義代替.
    在方法體末端的"?d=+"new Date()", 表示通過(guò)當(dāng)前時(shí)間來(lái)改變網(wǎng)頁(yè)請(qǐng)求, 從而實(shí)現(xiàn)刷新.
    否則瀏覽器緩存的原因會(huì)導(dǎo)致不刷新.
    --%>

2.3 驗(yàn)證碼的校驗(yàn)

index.jsp

<form action="<%=request.getContextPath()%>/servlet/LoginServlet" method="post">
    驗(yàn)證碼: <input type="text" name="captchaNo" />
    <img alt="captcha" id="captcha" src="<%=request.getContextPath()%>/servlet/ImageServlet" />
    <a href="javascript:(function(){document.getElementById('captcha').src='<%=request.getContextPath()%>/servlet/ImageServlet?d='+new Date();})();">看不清楚</a>
    <div><input type="submit" value="提交" /></div>
</form>

LoginServlet.java

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String captcha = request.getParameter("captchaNo").toUpperCase();
    System.out.println(captcha);
    System.out.println(request.getSession().getAttribute("piccode"));
    if (request.getSession().getAttribute("piccode").equals(captcha)) response.sendRedirect("/success.jsp");
    else response.sendRedirect("/index.jsp");
    System.out.println("驗(yàn)證完成===========");
}

Test.java

public static int getCorrectColor(int a){
    Random ran = new Random();
    int i = ran.nextInt(41) + (255 - a - 20);
    i = i > 0 ? i : 0;
    i = i > 255 ? 255 : i;
    System.out.print(i+" ");
    return i;
}

第三章 使用Jcaptcha組件實(shí)現(xiàn)驗(yàn)證碼

  • Jcaptcha: 一個(gè)用來(lái)生成圖形驗(yàn)證碼的Java開源組件,使用非常簡(jiǎn)單方便. 與Spring組合使用,可產(chǎn)生多種形式的驗(yàn)證碼.
  • Kaptcha: 一個(gè)非常使用的驗(yàn)證碼生成工具, 它是可以配置的, 可以生成各種各樣的驗(yàn)證碼.

Jcaptcha組件實(shí)現(xiàn)驗(yàn)證碼實(shí)例

項(xiàng)目案例

  • JSP禁用緩存的方式 response.setHeader( "Pragma", "no-cache" ); setDateHeader("Expires", 0);的用法和什么意思

JSP禁用緩存的方式 使用服務(wù)器端控制AJAX頁(yè)面緩存: response.setHeader( "Pragma", "no-cache" ); response.addHeader( "Cache-Control", "must-revalidate" ); response.addHeader( "Cache-Control", "no-cache" ); response.addHeader( "Cache-Control", "no-store" ); response.setDateHeader("Expires", 0); 單純的使用 xmlhttp.setRequestHeader("Cache-Control","no-cache")無(wú)效。

Cache-Control頭域 Cache-Control指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制。 在請(qǐng)求消息或響應(yīng)消息中設(shè)置Cache-Control并不會(huì)修改另一個(gè)消息處理過(guò)程中的緩存處理過(guò)程宇弛。 請(qǐng)求時(shí)的緩存指令包括no-cache嫌变、no-store、max-age嘉蕾、max-stale肪康、min-fresh、only-if-cached. 響應(yīng)消息中的指令包括public长踊、private、no-cache萍倡、no-store身弊、no-transform、must-revalidate列敲、proxy-revalidate阱佛、max-age。 各個(gè)消息中的指令含義如下: Public指示響應(yīng)可被任何緩存區(qū)緩存戴而。   Private指示對(duì)于單個(gè)用戶的整個(gè)或部分響應(yīng)消息凑术,不能被共享緩存處理。這允許服務(wù)器僅僅描述當(dāng)用戶的部分響應(yīng)消息所意,此響應(yīng)消息對(duì)于其他用戶的請(qǐng)求無(wú)效淮逊。   no-cache指示請(qǐng)求或響應(yīng)消息不能緩存   no-store用于防止重要的信息被無(wú)意的發(fā)布。在請(qǐng)求消息中發(fā)送將使得請(qǐng)求和響應(yīng)消息都不使用緩存扶踊。   max-age指示客戶機(jī)可以接收生存期不大于指定時(shí)間(以秒為單位)的響應(yīng)壮莹。   min-fresh指示客戶機(jī)可以接收響應(yīng)時(shí)間小于當(dāng)前時(shí)間加上指定時(shí)間的響應(yīng)。   max-stale指示客戶機(jī)可以接收超出超時(shí)期間的響應(yīng)消息姻檀。如果指定max-stale消息的值命满,那么客戶機(jī)可以接收超出超時(shí)期指定值之內(nèi)的響應(yīng)消息。

禁用IE緩存 HTTP消息報(bào)頭包括普通報(bào)頭绣版、請(qǐng)求報(bào)頭胶台、響應(yīng)報(bào)頭、實(shí)體報(bào)頭杂抽。 普通報(bào)頭中的Cache-Control用于指定緩存指令诈唬,緩存指令是單向的(響 應(yīng)中出現(xiàn)的緩存指令在請(qǐng)求中未必會(huì)出現(xiàn)).且是獨(dú)立的(一個(gè)消息的緩存指令不會(huì)影響另一個(gè)消息處理的緩存機(jī)制),HTTP1.0使用的類似的報(bào)頭域?yàn)镻ragma缩麸。 請(qǐng)求時(shí)的緩存指令包括:no-cache(用于指示請(qǐng)示或響應(yīng)消息不能緩存)铸磅、no-store、max-age杭朱、max-stale阅仔、min-fresh、only-if-cached弧械; 響應(yīng)時(shí)的緩存指令包括:public八酒、private、no-cache刃唐、no-store羞迷、no-transform界轩、must-revalidate、proxy-revalidate衔瓮、max-age浊猾、s-maxage。

例:為了指示IE瀏覽器(客戶端)不要緩存頁(yè)面热鞍,服務(wù)器端的jsp程序可以編寫如下: response.setHeader(“Cache-Control”, “no-cache”); //response.setHeader(“Pragma”, “no-cache”);作用相當(dāng)于上行代碼葫慎,通常兩者合用

Expires實(shí)體報(bào)頭域給出響應(yīng)過(guò)期的日期和時(shí)間。 為了讓代理服務(wù)器或?yàn)g覽器在一段時(shí)間以后更新緩存中(再次訪問曾訪問過(guò)的頁(yè)面時(shí)碍现,直接從緩存中加載幅疼,縮短響應(yīng)時(shí)間和降低服務(wù)器負(fù)載)的頁(yè)面米奸, 我們可以使用Expires實(shí)體報(bào)頭域指定頁(yè)面過(guò)期時(shí)間昼接。 例:Expires:Thu,15 Sep 2006 16:23:12 GMT HTTP1.1的客戶端和緩存必須將其他非法的日期格式(包括0)看作已經(jīng)過(guò)期。如:為了讓瀏覽器不要緩存頁(yè)面悴晰,也可以利用Expires實(shí)體報(bào)關(guān)域慢睡,設(shè)置為0,jsp程序如下: response.setDateHeader(“Expires”, “0”);

jcaptcha使用默認(rèn)樣式生成的驗(yàn)證碼比較難以識(shí)別铡溪,所以需要自定義驗(yàn)證碼的樣式漂辐,包括,背景色棕硫、背景大小髓涯、字體、字體大小哈扮、生成的字符數(shù)等纬纪。相對(duì)與kaptcha比較復(fù)雜。

純代碼實(shí)現(xiàn)jcaptcha驗(yàn)證碼

1滑肉、首先創(chuàng)建一個(gè)javaWeb工程添加jcaptcha包和它所依賴的包.

commons-collections-3.2.jar
commons-logging-1.2.jar
jcaptcha-1.0-all.jar

2包各、創(chuàng)建一個(gè)jcaptcha單例的Service類,這里是設(shè)置驗(yàn)證碼樣式的關(guān)鍵部分靶庙,代碼如下:

package cn.v5cn.jcaptchatest.custom;
 
import java.awt.Font;
 
import com.octo.captcha.CaptchaFactory;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomRangeColorGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.RandomTextPaster;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.word.FileDictionary;
import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import com.octo.captcha.engine.GenericCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.octo.captcha.service.multitype.GenericManageableCaptchaService;
 
public class CaptchaServiceSingleton {
    private static ImageCaptchaService service = null;
 
    public static ImageCaptchaService getService(){
        if(service == null)
            service = generatorCaptchaService();
        return service;
    }
    /**
     * 根據(jù)SpringBean的配置文件編寫的代碼實(shí)現(xiàn)
     * */
    public static ImageCaptchaService generatorCaptchaService(){
        //生成隨機(jī)顏色问畅,參數(shù)分別表示RGBA的取值范圍
        RandomRangeColorGenerator textColor = new RandomRangeColorGenerator(new int[]{0,255},new int[]{0,180},new int[]{0,210},new int[]{255,255});
        //隨機(jī)文字多少和顏色,參數(shù)1和2表示最少生成多少個(gè)文字和最多生成多少個(gè)
        RandomTextPaster randomTextPaster = new RandomTextPaster(4, 5, textColor,true);
        //生成背景的大小這里是寬85高40的圖片六荒,也可以設(shè)置背景顏色和隨機(jī)背景顏色护姆,這里使用默認(rèn)的白色
        UniColorBackgroundGenerator colorbgGen = new UniColorBackgroundGenerator(85,40);
        //隨機(jī)生成的字體大小和字體類型,參數(shù)1和2表示最小和最大的字體大小掏击,第三個(gè)表示隨機(jī)的字體
        RandomFontGenerator randomFontGenerator = new RandomFontGenerator(20, 25, new Font[]{new Font("Arial", 0, 10),new Font("Tahoma",0,10)});
        //結(jié)合上面的對(duì)象構(gòu)件一個(gè)從文本生成圖片的對(duì)象
        ComposedWordToImage cwti = new ComposedWordToImage(randomFontGenerator,colorbgGen,randomTextPaster);
        //隨機(jī)文本的字典签则,這里是使用jcaptcha-1.0-all.jar中的文本字典,字典名稱為toddlist.properties
        ComposeDictionaryWordGenerator cdwg = new ComposeDictionaryWordGenerator(new FileDictionary("toddlist"));
 
        GimpyFactory gf = new GimpyFactory(cdwg, cwti);
 
        GenericCaptchaEngine gce = new GenericCaptchaEngine(new CaptchaFactory[]{gf});
        //返回一個(gè)Service對(duì)象铐料,這里180是驗(yàn)證碼存在的時(shí)間渐裂,單位是秒豺旬,200000是最大存儲(chǔ)大小
        return new GenericManageableCaptchaService(gce,180,200000,75000);
    }
}

3、創(chuàng)建一個(gè)生成驗(yàn)證碼的Servlet柒凉,代碼如下:

package cn.v5cn.jcaptchatest.custom;
 
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
 
public class CustomServlet extends HttpServlet {
 
    private static final long serialVersionUID = 169310818225761427L;
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        byte[] captChallengeAsJpeg = null;
         
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
         
        String captchaId = req.getSession().getId();
        BufferedImage challenge = CaptchaServiceSingleton.getService().getImageChallengeForID(captchaId,req.getLocale());
         
        JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
        jpegEncoder.encode(challenge);
         
        captChallengeAsJpeg = jpegOutputStream.toByteArray();
         
         resp.setHeader("Cache-Control", "no-store");
         resp.setHeader("Pragma", "no-cache");
         resp.setDateHeader("Expires", 0);
         resp.setContentType("image/jpeg");
          
         ServletOutputStream respOutputStream = resp.getOutputStream();
         respOutputStream.write(captChallengeAsJpeg);
         respOutputStream.flush();
         respOutputStream.close();
    }
}

4族阅、在Web.xml中注冊(cè)這個(gè)Servlet,代碼如下:

<servlet>
    <servlet-name>generateValidateCode</servlet-name>
    <servlet-class>cn.v5cn.jcaptchatest.custom.CustomServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>generateValidateCode</servlet-name>
    <url-pattern>/cgvc</url-pattern>
  </servlet-mapping>

5膝捞、編寫一個(gè)使用驗(yàn)證碼的頁(yè)面坦刀,代碼如下:

<form action="valiServlet" method="post">
    <input type="text" name="customgvc">
    ![](cgvc)
    <input type="submit" value="提交">
</form>

6、編寫一個(gè)驗(yàn)證Servlet并在web.xml中注冊(cè)蔬咬,代碼分別如下:

package cn.v5cn.jcaptchatest.custom;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class ValidateServlet extends HttpServlet {
 
    private static final long serialVersionUID = -7173743572400866269L;
     
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String captchaId = req.getSession().getId();
         
        String validateCode = req.getParameter("customgvc");
         
        boolean validateResult = CaptchaServiceSingleton.getService().validateResponseForID(captchaId, validateCode);
        if(validateResult)
            resp.sendRedirect("success.html");
        else
            resp.sendRedirect("fail.html");
    }
}
<servlet>
    <servlet-name>validatServlet</servlet-name>
    <servlet-class>cn.v5cn.jcaptchatest.custom.ValidateServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>validatServlet</servlet-name>
    <url-pattern>/valiServlet</url-pattern>
  </servlet-mapping>

第四章 使用Kaptcha組件實(shí)現(xiàn)驗(yàn)證碼制作

4.1 字母數(shù)字組合驗(yàn)證碼的實(shí)現(xiàn)

web.xml

    <!--kaptcha驗(yàn)證碼配置-->
    <servlet>
        <servlet-name>kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <param-name>kaptcha.border</param-name>
            <param-value>no</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.font.color</param-name>
            <param-value>black</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.char.space</param-name>
            <param-value>5</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>kaptcha</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
    </servlet-mapping>
    <!--
    kaptcha.border:是否顯示邊框鲤遥。
    kaptcha.textproducer.font.color:字體顏色
    kaptcha.textproducer.char.space:字符間距
    更多的屬性設(shè)置可以在com.google.code.kaptcha.Constants類中找到。其中包括:
    kaptcha.border.color:邊框顏色
    kaptcha.border.thickness:邊框?qū)挾?    kaptcha.textproducer.char.length:產(chǎn)生字符的長(zhǎng)度
    kaptcha.textproducer.font.size:產(chǎn)生字符的大小
    kaptcha.image.width:產(chǎn)生圖片的寬度
    kaptcha.image.height:產(chǎn)生圖片的高度
    -->

index.jsp

    <form action="${pageContext.request.contextPath}/kaptcha" method="post">
        <input type="text" name="kaptchaValidate">
        <img id="vcode"onclick="(function() {document.getElementById('vcode').src
        ='${pageContext.request.contextPath}/kaptcha.jpg?'+new Date();

        })()" title="點(diǎn)擊更換" style="vertical-align: middle;" alt="驗(yàn)證圖片"
        src="${pageContext.request.contextPath}/kaptcha.jpg" height="35" width="80">
        <input type="submit" value="提交">
    </form>

KaptchaValidateServlet.java

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        String validate = request.getParameter("kaptchaValidate");
        String validateCode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);

        if (validate ==null || validateCode == null) response.sendRedirect("/index.jsp");
        else if (!validateCode.equals(validate)) response.sendRedirect("/index.jsp");
        else response.sendRedirect("/success.jsp");
    }

4.2 Kaptcha的詳細(xì)配置

<!--kaptcha驗(yàn)證碼配置-->
    <servlet>
        <servlet-name>kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <description>圖片邊框, yes or no</description>
            <param-name>kaptcha.border</param-name>
            <param-value>yes</param-value>
        </init-param>
        <init-param>
            <description>邊框顏色, white,black,blue...</description>
            <param-name>kaptcha.border.color</param-name>
            <param-value>blue</param-value>
        </init-param>
        <init-param>
            <description>邊框厚度,正整數(shù)</description>
            <param-name>kaptcha.border.thickness</param-name>
            <param-value>2</param-value>
        </init-param>
<!--        <init-param>
            <description>圖片寬度</description>
            <param-name>kaptcha.image.width</param-name>
            <param-value>80</param-value>
        </init-param>
        <init-param>
            <description>圖片高度</description>
            <param-name>kaptcha.image.height</param-name>
            <param-value>35</param-value>
        </init-param>-->
<!--       <init-param>
            <description>圖片實(shí)現(xiàn)類</description>
            <param-name>kaptcha.producer.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.DefaultKaptcha</param-value>
        </init-param>-->
        <init-param>
            <description>文本實(shí)現(xiàn)類, 類似文本字符集</description>
            <param-name>kaptcha.textproducer.impl</param-name>
            <param-value>ArithmeticIdentify</param-value>
            <!--<param-value>ChineseTest</param-value>-->
        </init-param>
<!--        <init-param>
            <description>文本集合,驗(yàn)證碼值從此集合中獲取</description>
            <param-name>kaptcha.textproducer.char.string</param-name>
            <param-value>我們就是這樣實(shí)現(xiàn)驗(yàn)證碼制作然后怎么呢文本類似大小設(shè)置長(zhǎng)度提交進(jìn)行盡興金星影響營(yíng)養(yǎng)</param-value>
        </init-param>-->
        <init-param>
            <description>設(shè)置字體</description>
            <param-name>kaptcha.textproducer.font.names</param-name>
            <param-value>Sim Sun</param-value>
        </init-param>
<!--        <init-param>
            <description>設(shè)置字體大小</description>
            <param-name>kaptcha.textproducer.font.size</param-name>
            <param-value>16</param-value>
        </init-param>-->
        <init-param>
            <description>字體顏色</description>
            <param-name>kaptcha.textproducer.font.color</param-name>
            <param-value>blue</param-value>
        </init-param>
        <init-param>
            <description>文字間隔</description>
            <param-name>kaptcha.textproducer.char.space</param-name>
            <param-value>10</param-value>
        </init-param>
<!--        <init-param>
            <description>干擾實(shí)現(xiàn)類</description>
            <param-name>kaptcha.noise.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.DefaultNoise</param-value>
        </init-param>-->
        <init-param>
            <description>干擾顏色</description>
            <param-name>kaptcha.noise.color</param-name>
            <param-value>yellow</param-value>
        </init-param>
<!--        <init-param>
            <description>背景實(shí)現(xiàn)類</description>
            <param-name>kaptcha.background.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.DefaultBackground</param-value>
        </init-param>-->
        <init-param>
            <description>背景顏色漸變, 開始顏色</description>
            <param-name>kaptcha.background.clear.from</param-name>
            <param-value>green</param-value>
        </init-param>
        <init-param>
            <description>背景顏色漸變, 結(jié)束顏色</description>
            <param-name>kaptcha.background.clear.to</param-name>
            <param-value>white</param-value>
        </init-param>
<!--        <init-param>
            <description>文字渲染器</description>
            <param-name>kaptcha.word.impl</param-name>
            <param-value>com.google.code.kaptcha.text.impl.DefaultWordRenderer</param-value>
        </init-param>-->
<!--       <init-param>
            <description>圖片樣式: FishEyeGimpy魚眼,WaterRipple水紋,ShadowGimpy陰影,默認(rèn)水紋</description>
            <param-name>kaptcha.obscurificator.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.ShadowGimpy</param-value>
        </init-param>-->
 <!--       <init-param>
            <description>session中存放驗(yàn)證碼的key鍵</description>
            <param-name>kaptcha.session.key</param-name>
            <param-value>KAPTCHA_SESSION_KEY</param-value>
        </init-param>-->


    </servlet>

    <servlet-mapping>
        <servlet-name>kaptcha</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
    </servlet-mapping>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末林艘,一起剝皮案震驚了整個(gè)濱河市盖奈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狐援,老刑警劉巖钢坦,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啥酱,居然都是意外死亡爹凹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門镶殷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)禾酱,“玉大人,你說(shuō)我怎么就攤上這事绘趋〔眨” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵埋心,是天一觀的道長(zhǎng)指郁。 經(jīng)常有香客問我,道長(zhǎng)拷呆,這世上最難降的妖魔是什么闲坎? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮茬斧,結(jié)果婚禮上腰懂,老公的妹妹穿的比我還像新娘。我一直安慰自己项秉,他們只是感情好绣溜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著娄蔼,像睡著了一般怖喻。 火紅的嫁衣襯著肌膚如雪底哗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天锚沸,我揣著相機(jī)與錄音跋选,去河邊找鬼。 笑死哗蜈,一個(gè)胖子當(dāng)著我的面吹牛前标,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播距潘,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炼列,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了音比?” 一聲冷哼從身側(cè)響起俭尖,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硅确,沒想到半個(gè)月后目溉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體明肮,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡菱农,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柿估。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片循未。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秫舌,靈堂內(nèi)的尸體忽然破棺而出的妖,到底是詐尸還是另有隱情,我是刑警寧澤足陨,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布嫂粟,位于F島的核電站,受9級(jí)特大地震影響墨缘,放射性物質(zhì)發(fā)生泄漏星虹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一镊讼、第九天 我趴在偏房一處隱蔽的房頂上張望宽涌。 院中可真熱鬧,春花似錦蝶棋、人聲如沸卸亮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)兼贸。三九已至段直,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間溶诞,已是汗流浹背坷牛。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留很澄,地道東北人京闰。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像甩苛,于是被迫代替她去往敵國(guó)和親蹂楣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容