利用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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章