使用JCaptcha生成驗證碼

zhaosoft1982發表於2010-03-09

使用JCaptcha工具包生成驗證碼

JCaptcha 官網地址 http://forge.octo.com/jcaptcha/confluence/display/general/Home

引入Lib包 (包括一些依賴包commons-collections等

從Servlet看起

 

 <!-- 驗證碼Servlet -->
  <servlet>
   <servlet-name>jcaptcha</servlet-name>
   <servlet-class>com.ighost.cms.common.checkcode.ImageCaptchaServlet</servlet-class>
  </servlet>
  <servlet-mapping>
   <servlet-name>jcaptcha</servlet-name>
   <url-pattern>/CheckCode.svl</url-pattern>
  </servlet-mapping>

 

 package com.ighost.cms.common.checkcode;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.octo.captcha.service.CaptchaServiceException;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 驗證碼生成Servlet
 * @author ghost
 *
 */
@SuppressWarnings("serial")
public class ImageCaptchaServlet extends HttpServlet {

 //驗證碼生成類
 private ImageCaptchaService imageCaptchaService;
 //Spring中的配置名稱
 private String beanName = "imageCaptchaService";
 
 /**
  * 初始化ImageCaptchaService 物件
  */
 @Override
 public void init(ServletConfig config) throws ServletException {
  System.out.println("servlet init is in");
  super.init(config);
  WebApplicationContext context = WebApplicationContextUtils
           .getWebApplicationContext(config.getServletContext());
  imageCaptchaService = (ImageCaptchaService)context.getBean(beanName,ImageCaptchaService.class);
 }
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  byte[] captchaChallengeAsJpeg = null;
  // the output stream to render the captcha image as jpeg into
  ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
  try {
   // get the session id that will identify the generated captcha.
   // the same id must be used to validate the response, the session id
   // is a good candidate!
   String captchaId = req.getSession().getId();
   // call the ImageCaptchaService getChallenge method
   BufferedImage challenge = imageCaptchaService
     .getImageChallengeForID(captchaId, req.getLocale());

   // a jpeg encoder
   JPEGImageEncoder jpegEncoder = JPEGCodec
     .createJPEGEncoder(jpegOutputStream);
   jpegEncoder.encode(challenge);
  } catch (IllegalArgumentException e) {
   resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   return;
  } catch (CaptchaServiceException e) {
   resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
   return;
  }

  captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

  // flush it in the response
  resp.setHeader("Cache-Control", "no-store");
  resp.setHeader("Pragma", "no-cache");
  resp.setDateHeader("Expires", 0);
  resp.setContentType("image/jpeg");
  ServletOutputStream responseOutputStream = resp.getOutputStream();
  responseOutputStream.write(captchaChallengeAsJpeg);
  responseOutputStream.flush();
  responseOutputStream.close();
 }

}

Servlet中需要的類在Bean中的配置

 

 <!-- 驗證碼生成器 -->
 <bean id="fastHashMapCaptchaStore" class="com.octo.captcha.service.captchastore.FastHashMapCaptchaStore"/>
 <bean id="captchaEngineEx" class="com.ighost.cms.common.checkcode.CaptchaEngineEx"/>
 <bean id="imageCaptchaService" class="com.ighost.cms.common.checkcode.CaptchaService">
  <constructor-arg type="com.octo.captcha.service.captchastore.CaptchaStore" index="0">
   <ref bean="fastHashMapCaptchaStore"/>
  </constructor-arg>
  <constructor-arg type="com.octo.captcha.engine.CaptchaEngine" index="1">
   <ref bean="captchaEngineEx"/>
  </constructor-arg>
  <constructor-arg index="2">
   <value>180</value>   
  </constructor-arg>
  <constructor-arg index="3">
   <value>100000</value>   
  </constructor-arg>
  <constructor-arg index="4">
   <value>75000</value>   
  </constructor-arg> 
 </bean>

具體完成生成的類

 

 package com.ighost.cms.common.checkcode;

import com.octo.captcha.engine.CaptchaEngine;
import com.octo.captcha.service.captchastore.CaptchaStore;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;

/*
 * 自定義的驗證碼生成器
 */
public class CaptchaService extends DefaultManageableImageCaptchaService {

 public CaptchaService(){
  super();
 }
 
 /**
  * @param minSeconds
  * @param maxStoreSize 最大快取大小
  * @param loadBefore
  */
 public CaptchaService(int minSeconds, int maxStoreSize, int loadBefore){
  super(minSeconds, maxStoreSize, loadBefore);
 }
 
 public CaptchaService(CaptchaStore captchaStore, CaptchaEngine captchaEngine,
       int minSeconds, int maxStroreSize, int loadBefore){
  super(captchaStore, captchaEngine, minSeconds, maxStroreSize, loadBefore);
 }
 
 /**
  * 重寫驗證方法
  * 掩蓋異常 當出現異常時判定為驗證失敗
  */
 @Override
 public Boolean validateResponseForID(String ID, Object response) {
  Boolean isHuman;
  
  try{
   isHuman = super.validateResponseForID(ID, response);
  }
  catch(Exception e){
   isHuman = false;   
  }
  
  return isHuman;
 }
}

 

 package com.ighost.cms.common.checkcode;

import java.awt.Color;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.GradientBackgroundGenerator;
import com.octo.captcha.component.image.color.SingleColorGenerator;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.BaffleTextDecorator;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;

/**
 * 自定義的驗證碼生成引擎
 * @author ghost
 *
 */
public class CaptchaEngineEx extends ListImageCaptchaEngine {

 /**
  * 生成驗證碼的具體方法
  */
 @Override
 protected void buildInitialFactories() {
  
  //驗證碼的最小長度
  Integer minAcceptedWordLength = new Integer(4);
  //驗證碼的最大長度
  Integer maxAcceptedWordLength = new Integer(5);
  
  //驗證碼圖片的高度寬度設定
  Integer imageHeight = new Integer(40);
  Integer imageWidth = new Integer(100);
  
  //驗證碼中顯示的字型大小
  Integer minFontSize = new Integer(20);
  Integer maxFontSize = new Integer(22);
  
  //隨機字元生成
  //abcdefghijklmnopqrstuvwxyz
  WordGenerator wordGenerator = new RandomWordGenerator("0123456789");
  
  //背景顏色隨機生成
  BackgroundGenerator backgroundGenerator = new GradientBackgroundGenerator(
    imageWidth, imageHeight, Color.white,Color.white);
 
  //字型隨機生成
  FontGenerator fontGenerator = new RandomFontGenerator(minFontSize, maxFontSize);
  
  //驗證碼的顏色
  SingleColorGenerator singleColor = new SingleColorGenerator(Color.blue);
  
  BaffleTextDecorator baffleTextDecorator = new BaffleTextDecorator(1, Color.white);
  //可以建立多個
  //LineTextDecorator lineTextDecorator = new LineTextDecorator(1, Color.blue);
  //TextDecorator[] textDecorator = new TextDecorator[2];
  //textDecorator[0] = lineTextDecorator;
  TextDecorator[] textDecorator = new TextDecorator[1];
  textDecorator[0] = baffleTextDecorator;
  
  TextPaster textPaster = new DecoratedRandomTextPaster(
    minAcceptedWordLength, maxAcceptedWordLength, singleColor,textDecorator);
  //生成圖片輸出
  WordToImage wordToImage = new ComposedWordToImage(
    fontGenerator, backgroundGenerator, textPaster);
  
  addFactory(new GimpyFactory(wordGenerator, wordToImage)); 
 }

}

最後在jsp頁面中只需使用如下呼叫即可

 

<img id="checkcode" alt="看不清,點選換一張" src="../CheckCode.svl" border="1px" onclick="this.src='../CheckCode.svl?date=' + new Date().getTime()">

相關文章