說說如何在登入頁實現生成驗證碼功能
1 引入驗證碼元件
開啟 simplecaptcha ofollow,noindex">官網 ,下載相應的 jar 包。示例中用的是 nl.captcha.simplecaptcha-1.2.1.jar。
2 自定義驗證碼服務
2.1 字元生成器
因為某些字元相似容易導致使用者誤輸,比如 i 與 1、z 與 2,所以我們自己定製了字元生成器:
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 中我們定義了驗證碼字符集。
2.2 驗證碼 Servlet
參考元件原始碼,我們寫了定製的驗證碼 Servlet:
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); } } }
- 在 COLORS 字符集中,我們可以指定驗證碼顏色,支援多種顏色。
- 在 FONTS 字型庫中,我們可以指定驗證碼字型,支援多種字型。
- 為 DefaultWordRenderer 方法傳入 COLORS 與 FONTS 引數,新建 DefaultWordRenderer 例項。
- 使用 Captcha.Builder() 建立 Captcha 例項。
- Captcha.Builder() 支援鏈式呼叫。它支援以下方法:
方法 | 說明 |
---|---|
addText() | 新增驗證碼字元。 |
addBackground() | 新增背景色。 |
addNoise() | 新增干擾線,在此我們添加了一段彎曲的線條作為干擾線。如果想要新增多個線條,那麼可以多次呼叫 addNoise()。還支援直線干擾線(StraightLineNoiseProducer)。 |
gimp() | 新增濾鏡,在此我們使用了波浪紋效果 RippleGimpyRenderer。 |
3 配置 web.xml
在 web.xml 配置 servlet,讓生成驗證碼功能成為服務,供前端呼叫:
<!-- 驗證碼--> <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 引入頁面
在登入頁中加入驗證碼輸入框與驗證碼圖片顯示功能:
<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 中取出驗證碼物件,判斷前端傳過來的驗證碼字元是否正確。
6 效果

7 錦上添花
當滑鼠移動到驗證碼圖片時,自動彈出友好提示,當用戶點選驗證碼時,更換圖片。

這裡的提示用的是 Opentip 元件。
初始化驗證碼:
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哈哈~