說說如何在登陸頁實現生成驗證碼功能

1 引入驗證碼組件

打開 simplecaptcha 官網,下載相應的 jar 包。示例中用的是 nl.captcha.simplecaptcha-1.2.1.jar。前端

2 自定義驗證碼服務

2.1 字符生成器

由於某些字符類似容易致使用戶誤輸,好比 i 與 一、z 與 2,因此咱們本身定製了字符生成器:java

public class CustomTextProducer implements TextProducer {
    private static final Random RAND = new SecureRandom();
    /**
     * 默認長度
     */
    private static final int DEFAULT_LENGTH = 4;
    /**
     * 字符集
     */
    private static final char[] DEFAULT_CHARS = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'k', 'm', 'n', 'p', 'r', 'w', 'x', 'y', '2', '3', '4', '5', '6', '7', '8'};
    private final int _length;
    private final char[] _srcChars;

    public CustomTextProducer() {
        this(DEFAULT_LENGTH, DEFAULT_CHARS);
    }

    public CustomTextProducer(int length, char[] srcChars) {
        this._length = length;
        this._srcChars = copyOf(srcChars, srcChars.length);
    }

    public String getText() {
        String capText = "";

        for (int i = 0; i < this._length; ++i) {
            capText = capText + this._srcChars[RAND.nextInt(this._srcChars.length)];
        }

        return capText;
    }

    private static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
        return copy;
    }
}
複製代碼

在 DEFAULT_CHARS 中咱們定義了驗證碼字符集。web

2.2 驗證碼 Servlet

參考組件源代碼,咱們寫了定製的驗證碼 Servlet:bash

public class CustomCaptchaServlet extends HttpServlet {

    static Logger logger = Logger.getLogger(CustomCaptchaServlet.class);

    private static final long serialVersionUID = 1L;
    private static int _width = 300;
    private static int _height = 50;

    /**
     * 顏色庫
     */
    private static final java.util.List<Color> COLORS = new ArrayList(2);

    /**
     * 字體庫
     */
    private static final java.util.List<Font> FONTS = new ArrayList(3);

    static {
        COLORS.add(new Color(24, 78, 190));

        FONTS.add(new Font("Geneva", 2, 48));
    }

    public CustomCaptchaServlet() {
    }

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        if (this.getInitParameter("captcha-height") != null) {
            _height = Integer.valueOf(this.getInitParameter("captcha-height")).intValue();
        }

        if (this.getInitParameter("captcha-width") != null) {
            _width = Integer.valueOf(this.getInitParameter("captcha-width")).intValue();
        }

    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            DefaultWordRenderer wordRenderer = new DefaultWordRenderer(COLORS, FONTS);

            //定義驗證碼
            Captcha captcha = (new Captcha.Builder(_width, _height)).addText(new
                    CustomTextProducer(), wordRenderer)
                    .addBackground(new FlatColorBackgroundProducer(new Color(255, 255, 255)))
                    .addNoise(new
                            CurvedLineNoiseProducer(COLORS.get(0), 3.0F)).gimp
                            (new
                                    RippleGimpyRenderer())
                    .build();

            //生成圖片
            CaptchaServletUtil.writeImage(resp, captcha.getImage());

            //寫入 Session
            req.getSession().setAttribute("simpleCaptcha", captcha);
        } catch (Exception e) {
            logger.error("自定義驗證碼生成規則", e);
        }
    }
}
複製代碼
  1. 在 COLORS 字符集中,咱們能夠指定驗證碼顏色,支持多種顏色。
  2. 在 FONTS 字體庫中,咱們能夠指定驗證碼字體,支持多種字體。
  3. 爲 DefaultWordRenderer 方法傳入 COLORS 與 FONTS 參數,新建 DefaultWordRenderer 實例。
  4. 使用 Captcha.Builder() 建立 Captcha 實例。
  5. Captcha.Builder() 支持鏈式調用。它支持如下方法:
方法 說明
addText() 添加驗證碼字符。
addBackground() 添加背景色。
addNoise() 添加干擾線,在此咱們添加了一段彎曲的線條做爲干擾線。若是想要添加多個線條,那麼能夠屢次調用 addNoise()。還支持直線干擾線(StraightLineNoiseProducer)。
gimp() 添加濾鏡,在此咱們使用了波浪紋效果 RippleGimpyRenderer。

3 配置 web.xml

在 web.xml 配置 servlet,讓生成驗證碼功能成爲服務,供前端調用:session

<!-- 驗證碼-->
<servlet>
	<servlet-name>StickyCaptcha</servlet-name>
	<servlet-class>com.deniro.jail.web.sys.CustomCaptchaServlet</servlet-class>
	<init-param>
		<param-name>width</param-name>
		<param-value>75</param-value>
	</init-param>
	<init-param>
		<param-name>height</param-name>
		<param-value>24</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>StickyCaptcha</servlet-name>
	<url-pattern>/stickyImg</url-pattern>
</servlet-mapping>
複製代碼

4 引入頁面

在登陸頁中加入驗證碼輸入框與驗證碼圖片顯示功能:app

<input class="field" type="text" id="validateCode" name="validateCode"
	  value=""
	  placeholder="驗證碼">
<img id="codeImg" src="${contextPath}/stickyImg"
							 alt="" width="150" height="24"/>
複製代碼

5 加入驗證邏輯

//檢查驗證碼是否正確
Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
if (validateCode == null || !captcha.isCorrect(validateCode)) {
	return fail("驗證碼不正確!");
}
複製代碼

從 Session 中取出驗證碼對象,判斷前端傳過來的驗證碼字符是否正確。dom

6 效果

7 錦上添花

當鼠標移動到驗證碼圖片時,自動彈出友好提示,當用戶點擊驗證碼時,更換圖片。ide

這裏的提示用的是 Opentip 組件。字體

初始化驗證碼:ui

initValidateCode: function () {
	var that = this;
	var $codeImg = $("#codeImg");
	var codeImgTip = new Opentip($codeImg, {showOn: null, style: 'dark'});//驗證碼圖片提示
	$codeImg.click(function () {//點擊驗證碼更新圖片
		that.changeValidateCode($(this));
		//$(this).attr("src", that.context_path + '/stickyImg?' + Math.floor(Math.random() * 100));
		codeImgTip.hide();
	}).mouseover(function () {//出現提示
		$codeImg.addClass("onElement");
		codeImgTip.setContent("看不清,換一張");
		codeImgTip.show();
	}).mouseout(function () {//隱藏提示
		$codeImg.removeClass("onElement");
		codeImgTip.hide();
	});
}
複製代碼

改變驗證碼:

/**
 * 改變驗證碼
 * @param $codeImg 驗證碼對象
 */
changeValidateCode: function ($codeImg) {
	$codeImg.attr("src", this.context_path + '/stickyImg?' + Math.floor(Math.random() * 100));
}
複製代碼

8 其它效果

8.1 陰影效果

new DropShadowGimpyRenderer()
複製代碼

8.2 魚眼效果

Captcha captcha = (new Captcha.Builder(_width, _height)).addText(new
	CustomTextProducer(), wordRenderer)
	.addBackground(new FlatColorBackgroundProducer(new Color(255, 255, 255)))
	.gimp
			(new
					FishEyeGimpyRenderer())
	.build();
複製代碼

由於魚眼效果自己已經很複雜咯,因此這裏去除了干擾線。

8.3 複雜波浪效果

圖片字符像水波同樣變形甚至發生部分重影現象,因此用這個濾鏡時,要注意字符集只使用一些簡單的字符。

new ShearGimpyRenderer()
複製代碼

8.4 抓取效果

圖片字符像被貓抓過了同樣,因此用這個濾鏡時,也要注意字符集的使用。

new StretchGimpyRenderer()
複製代碼

8.5 多條幹擾線

Captcha captcha = (new Captcha.Builder(_width, _height)).addText(new
			CustomTextProducer(), wordRenderer)
			.addBackground(new FlatColorBackgroundProducer(new Color(255, 255, 255)))
			.addNoise(new
					CurvedLineNoiseProducer(COLORS.get(0), 3.0F))
	.addNoise(new
			CurvedLineNoiseProducer(COLORS.get(0), 3.0F))
			.gimp
					(new
							RippleGimpyRenderer())
			.build();
複製代碼

是否是很酷呀 O(∩_∩)O哈哈~

相關文章
相關標籤/搜索