利用jcaptcha生成自定義驗證碼
導讀:
jcaptcha是一個開源的用來生成圖形驗證碼的Java開源組件,使用起來也是非常的簡單方便。不過,很多網友抱怨該組件默認的圖片比較大,影響網頁的美觀。由於代碼過於簡單,以至於找不到地方修改。由於tycho(我正在開發的程序)也需要利用該組件生成驗證碼,所以簡單地研究了一下。發現 jcapthca是非常強大的,不光是可以生成圖片式的驗證碼,還可以生成聲音式的(新浪就使用了雙重驗證碼)。大家可以到這裏下載,並導入到你的工程。
若要利用jcaptcha生成自定義樣式的驗證碼,首先需要爲其創建一個驗證碼引擎,或者說驗證碼方案類。如下:
publicclassMyImageCaptchaEngine
extendsListImageCaptchaEngine {
protectedvoidbuildInitialFactories(){
// 隨機生成的字符
WordGenerator wgen = newRandomWordGenerator(
"abcdefghijklmnopqrstuvwxyz123456789");
RandomRangeColorGenerator cgen =
newRandomRangeColorGenerator(
newint[]{0, 100}, newint[]{0, 100},
newint[]{0, 100});
// 文字顯示的個數
TextPaster textPaster = newRandomTextPaster(newInteger(6),
newInteger(6), cgen, true);
// 圖片的大小
BackgroundGenerator backgroundGenerator =
newFunkyBackgroundGenerator(
newInteger(150), newInteger(50));
// 字體格式
Font[]fontsList = newFont[]{
newFont("Arial", 0, 10),
newFont("Tahoma", 0, 10), newFont("Verdana", 0, 10), };
// 文字的大小
FontGenerator fontGenerator =
newRandomFontGenerator(newInteger(15),
newInteger(30), fontsList);
WordToImage wordToImage = newComposedWordToImage(fontGenerator,
backgroundGenerator, textPaster);
this.addFactory(newGimpyFactory(wgen, wordToImage));
}
}
上面的自定義驗證碼引擎繼承了ListImageCaptchaEngine類,那麼它將會生成一個彩色的驗證碼。當然,你還可以繼承其它的類來生成不同的驗證碼,如:聲音格式的驗證碼。具體請參照官方網站。
接下來,我們要爲其定義一個單例類的全局對象,並在構造方法中注入我們的引擎。如下:
publicclassCaptchaServiceSingleton {
privatestaticDefaultManageableImageCaptchaService instance =
newDefaultManageableImageCaptchaService(
newFastHashMapCaptchaStore(),
newMyImageCaptchaEngine(),
180,
100000,
75000);
publicstaticImageCaptchaService getInstance(){
returninstance;
}
}
爲什麼要創建爲單例的?當然,你可以不創建爲單例類,但是你會發現,每次打開有驗證碼的畫面時,驗證碼顯示的都很慢,那是因爲創建該對象的實例時,需要在內存中創建背景圖像、描點、邊框等等工作的原因。而創建一次後,圖片框架就不需要再次創建了,以後每次調用該實例時,只是生成隨機字符並嵌入圖片中即可。
接下來要做的就是,生成一個servlet,用來和前臺頁面交互,如下:
publicclassImageCaptchaServlet extendsHttpServlet {
publicvoidinit(ServletConfig servletConfig)
throwsServletException {
super.init(servletConfig);
}
// 複寫doGet
protectedvoiddoGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throwsServletException, IOException{
byte[]captchaChallengeAsJpeg = null;
ByteArrayOutputStreamjpegOutputStream =
newByteArrayOutputStream();
try{
StringcaptchaId =
httpServletRequest.getSession().getId();
BufferedImagechallenge =
CaptchaServiceSingleton.getInstance()
.getImageChallengeForID(
captchaId,httpServletRequest.getLocale());
JPEGImageEncoder jpegEncoder =
JPEGCodec.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
}catch(IllegalArgumentExceptione){
httpServletResponse.sendError(
HttpServletResponse.SC_NOT_FOUND);
return;
}catch(CaptchaServiceException e){
httpServletResponse.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream =
httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
配置這個servlet到web.xml文件,以使其生效。
>
>jcaptcha>
>
com.mxjava.tycho.servlet.captcha.ImageCaptchaServlet
>
>0>
>
>
>jcaptcha>
>/jcaptcha>
>
完成了以上部分後,就可以在前臺頁面寫下用於顯示驗證碼的代碼:
<input type='text' name='j_captcha_response' value='>
還記得我們在servlet裏的配置嗎?上面的上面的src=”jcaptcha” _fcksavedurl="”jcaptcha”" _fcksavedurl="”jcaptcha”" 就是調用了上面的servlet。
最後,也是最重要的一部分,就是在後臺編寫驗證代碼。
// 驗證碼是否正確flag
BooleanisResponseCorrect = Boolean.FALSE;
// 取session用來驗證是否在同一session中
StringcaptchaId = ServletActionContext.getRequest()
.getSession().getId();
// 取前臺輸入的難證碼
Stringresponse = ServletActionContext.getRequest()
.getParameter("j_captcha_response");
try{
// 取得驗證對象,並檢驗session和輸入驗證碼是否正確
isResponseCorrect = CaptchaServiceSingleton.getInstance()
.validateResponseForID(captchaId, response);
// 如果不正確
if(!isResponseCorrect){
// 輸出錯誤信息
super.addFieldError(Constants.REQ_ERR_MESSAGE, super
.getText(Constants.VALIDATION_VERIFICATION_CODE_ERROR));
returnINPUT;
}
}catch(CaptchaServiceException e){
// 根據你的需求做處理。
}
至此,我們自定義的驗證碼就算完成了。值得注意的是,在修改圖片大小時,要比圖片上的文字大,不然會拋異常。
本文轉自
http://www.mxjava.com/weblog/index.php/technic/java/8#more-8
jcaptcha是一個開源的用來生成圖形驗證碼的Java開源組件,使用起來也是非常的簡單方便。不過,很多網友抱怨該組件默認的圖片比較大,影響網頁的美觀。由於代碼過於簡單,以至於找不到地方修改。由於tycho(我正在開發的程序)也需要利用該組件生成驗證碼,所以簡單地研究了一下。發現 jcapthca是非常強大的,不光是可以生成圖片式的驗證碼,還可以生成聲音式的(新浪就使用了雙重驗證碼)。大家可以到這裏下載,並導入到你的工程。
若要利用jcaptcha生成自定義樣式的驗證碼,首先需要爲其創建一個驗證碼引擎,或者說驗證碼方案類。如下:
publicclassMyImageCaptchaEngine
extendsListImageCaptchaEngine {
protectedvoidbuildInitialFactories(){
// 隨機生成的字符
WordGenerator wgen = newRandomWordGenerator(
"abcdefghijklmnopqrstuvwxyz123456789");
RandomRangeColorGenerator cgen =
newRandomRangeColorGenerator(
newint[]{0, 100}, newint[]{0, 100},
newint[]{0, 100});
// 文字顯示的個數
TextPaster textPaster = newRandomTextPaster(newInteger(6),
newInteger(6), cgen, true);
// 圖片的大小
BackgroundGenerator backgroundGenerator =
newFunkyBackgroundGenerator(
newInteger(150), newInteger(50));
// 字體格式
Font[]fontsList = newFont[]{
newFont("Arial", 0, 10),
newFont("Tahoma", 0, 10), newFont("Verdana", 0, 10), };
// 文字的大小
FontGenerator fontGenerator =
newRandomFontGenerator(newInteger(15),
newInteger(30), fontsList);
WordToImage wordToImage = newComposedWordToImage(fontGenerator,
backgroundGenerator, textPaster);
this.addFactory(newGimpyFactory(wgen, wordToImage));
}
}
上面的自定義驗證碼引擎繼承了ListImageCaptchaEngine類,那麼它將會生成一個彩色的驗證碼。當然,你還可以繼承其它的類來生成不同的驗證碼,如:聲音格式的驗證碼。具體請參照官方網站。
接下來,我們要爲其定義一個單例類的全局對象,並在構造方法中注入我們的引擎。如下:
publicclassCaptchaServiceSingleton {
privatestaticDefaultManageableImageCaptchaService instance =
newDefaultManageableImageCaptchaService(
newFastHashMapCaptchaStore(),
newMyImageCaptchaEngine(),
180,
100000,
75000);
publicstaticImageCaptchaService getInstance(){
returninstance;
}
}
爲什麼要創建爲單例的?當然,你可以不創建爲單例類,但是你會發現,每次打開有驗證碼的畫面時,驗證碼顯示的都很慢,那是因爲創建該對象的實例時,需要在內存中創建背景圖像、描點、邊框等等工作的原因。而創建一次後,圖片框架就不需要再次創建了,以後每次調用該實例時,只是生成隨機字符並嵌入圖片中即可。
接下來要做的就是,生成一個servlet,用來和前臺頁面交互,如下:
publicclassImageCaptchaServlet extendsHttpServlet {
publicvoidinit(ServletConfig servletConfig)
throwsServletException {
super.init(servletConfig);
}
// 複寫doGet
protectedvoiddoGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throwsServletException, IOException{
byte[]captchaChallengeAsJpeg = null;
ByteArrayOutputStreamjpegOutputStream =
newByteArrayOutputStream();
try{
StringcaptchaId =
httpServletRequest.getSession().getId();
BufferedImagechallenge =
CaptchaServiceSingleton.getInstance()
.getImageChallengeForID(
captchaId,httpServletRequest.getLocale());
JPEGImageEncoder jpegEncoder =
JPEGCodec.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
}catch(IllegalArgumentExceptione){
httpServletResponse.sendError(
HttpServletResponse.SC_NOT_FOUND);
return;
}catch(CaptchaServiceException e){
httpServletResponse.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream =
httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
配置這個servlet到web.xml文件,以使其生效。
>
>jcaptcha>
>
com.mxjava.tycho.servlet.captcha.ImageCaptchaServlet
>
>0>
>
>
>jcaptcha>
>/jcaptcha>
>
完成了以上部分後,就可以在前臺頁面寫下用於顯示驗證碼的代碼:
<input type='text' name='j_captcha_response' value='>
還記得我們在servlet裏的配置嗎?上面的上面的src=”jcaptcha” _fcksavedurl="”jcaptcha”" _fcksavedurl="”jcaptcha”" 就是調用了上面的servlet。
最後,也是最重要的一部分,就是在後臺編寫驗證代碼。
// 驗證碼是否正確flag
BooleanisResponseCorrect = Boolean.FALSE;
// 取session用來驗證是否在同一session中
StringcaptchaId = ServletActionContext.getRequest()
.getSession().getId();
// 取前臺輸入的難證碼
Stringresponse = ServletActionContext.getRequest()
.getParameter("j_captcha_response");
try{
// 取得驗證對象,並檢驗session和輸入驗證碼是否正確
isResponseCorrect = CaptchaServiceSingleton.getInstance()
.validateResponseForID(captchaId, response);
// 如果不正確
if(!isResponseCorrect){
// 輸出錯誤信息
super.addFieldError(Constants.REQ_ERR_MESSAGE, super
.getText(Constants.VALIDATION_VERIFICATION_CODE_ERROR));
returnINPUT;
}
}catch(CaptchaServiceException e){
// 根據你的需求做處理。
}
至此,我們自定義的驗證碼就算完成了。值得注意的是,在修改圖片大小時,要比圖片上的文字大,不然會拋異常。
本文轉自
http://www.mxjava.com/weblog/index.php/technic/java/8#more-8
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.