打開 simplecaptcha 官網,下載相應的 jar 包。示例中用的是 nl.captcha.simplecaptcha-1.2.1.jar。前端
由於某些字符類似容易致使用戶誤輸,好比 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
參考組件源代碼,咱們寫了定製的驗證碼 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);
}
}
}
複製代碼
方法 | 說明 |
---|---|
addText() | 添加驗證碼字符。 |
addBackground() | 添加背景色。 |
addNoise() | 添加干擾線,在此咱們添加了一段彎曲的線條做爲干擾線。若是想要添加多個線條,那麼能夠屢次調用 addNoise()。還支持直線干擾線(StraightLineNoiseProducer)。 |
gimp() | 添加濾鏡,在此咱們使用了波浪紋效果 RippleGimpyRenderer。 |
在 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>
複製代碼
在登陸頁中加入驗證碼輸入框與驗證碼圖片顯示功能:app
<input class="field" type="text" id="validateCode" name="validateCode"
value=""
placeholder="驗證碼">
<img id="codeImg" src="${contextPath}/stickyImg"
alt="" width="150" height="24"/>
複製代碼
//檢查驗證碼是否正確
Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
if (validateCode == null || !captcha.isCorrect(validateCode)) {
return fail("驗證碼不正確!");
}
複製代碼
從 Session 中取出驗證碼對象,判斷前端傳過來的驗證碼字符是否正確。dom
當鼠標移動到驗證碼圖片時,自動彈出友好提示,當用戶點擊驗證碼時,更換圖片。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));
}
複製代碼
new DropShadowGimpyRenderer()
複製代碼
Captcha captcha = (new Captcha.Builder(_width, _height)).addText(new
CustomTextProducer(), wordRenderer)
.addBackground(new FlatColorBackgroundProducer(new Color(255, 255, 255)))
.gimp
(new
FishEyeGimpyRenderer())
.build();
複製代碼
由於魚眼效果自己已經很複雜咯,因此這裏去除了干擾線。
圖片字符像水波同樣變形甚至發生部分重影現象,因此用這個濾鏡時,要注意字符集只使用一些簡單的字符。
new ShearGimpyRenderer()
複製代碼
圖片字符像被貓抓過了同樣,因此用這個濾鏡時,也要注意字符集的使用。
new StretchGimpyRenderer()
複製代碼
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哈哈~