1. 程式人生 > >JCaptcha開源元件-生成第一個驗證碼

JCaptcha開源元件-生成第一個驗證碼

1.  介紹

jcaptcha是一個開源的用來生成圖形驗證碼的Java開源元件,不光是可以生成圖片式的驗證碼,還可以生成聲音式的(新浪就使用了雙重驗證碼)。

2.      Spring

JCaptcha儘可能地遵循IOC(Inversion of Control)模式,使其能夠為應用程式更加簡潔的建立元件.

另一方面,Spring框架也允許通過XML配置檔案宣告的方式使用JCaptcha元件。所以每一個jCaptcha的單一元件能夠通過Spring配置檔案定義並且例項化。

3.       關聯包

使用該開源元件時,需要配置以下3個包:

commons-collections-3.2.1.jar

commons-logging-1.1.1.jar

jcaptcha-1.0-all.jar

第3個包是該開源元件的核心包,上面兩個包是核心包在執行時需要用到的基本包。

4.       簡單的使用

a.       呼叫驗證碼的index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>驗證碼生成測試</title>
  </head>
  
  <body>
    <img src="CaptchaImage" />
  </body>
</html>

b.      配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>	
  <servlet>
    <servlet-name>Image</servlet-name>
    <servlet-class>sample.Image</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Image</servlet-name>
    <url-pattern>/CaptchaImage</url-pattern>
  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

c.       編寫核心包配置類:SimpleCustomImageService.java

package sample;
 
import java.awt.Color;
import com.octo.captcha.CaptchaFactory;
import com.octo.captcha.component.image.backgroundgenerator.FunkyBackgroundGenerator;
import com.octo.captcha.component.image.color.SingleColorGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.RandomTextPaster;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.engine.image.gimpy.SimpleListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
import com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
/*************************************************************
 * 
 * 名稱:SimpleCustomImageService
 * 型別:宣告類
 * 作用:呼叫 jcaptcha 包內方法,進行預設初始化。
 * 內容:getInstance()方法
 *     initializeService()
 * 編寫:劉武志
 * 日期:2013-04-11
 *
 *************************************************************/
public class SimpleCustomImageService {
	private static ImageCaptchaService instance = initializeService();

	/**
	 * 方法名:getInstance()
	 * 功    能:用於獲取 ImageCaptchaService 型別的返回值
	 * 返回型別:ImageCaptchaService
	 * 
	 */
	public static ImageCaptchaService getInstance() {
		return instance;
	}
	/**
	 * 
	 * 方法名:initializeService
	 * 功    能:該方法用於完成驗證碼生成的基本設定
	 * 返回型別:ImageCaptchaService
	 * 
	 */
	private static ImageCaptchaService initializeService() {
		// 設定隨機字型大小的範圍
		RandomFontGenerator fonts = new RandomFontGenerator(new Integer(20),
					new Integer(25));
		// ***FunkyBackgroundGenerator類,可以設定四種顏色點混合而成的背景***
		// 第一個引數是圖片寬度
		// 第二個引數是圖片高度
		// 第三至第六個引數分別是圖片中,左上,左下,右上,右下四個部分的顏色點的顏色
		// 第七個引數是顏色混雜的程度,如:0.5為顏色相互混合的點佔一半,最大1.0
		// ***設定四個顏色除了可以使用SingleColorGenerator外,
		// ***應該也可以使用RandomListColorGenerator類,讓每個部分的顏色都不固定
		SingleColorGenerator leftUpColor = new SingleColorGenerator(Color.RED);
		SingleColorGenerator leftDownColor = new SingleColorGenerator(Color.YELLOW);
		SingleColorGenerator rightUpColor = new SingleColorGenerator(Color.BLUE);
		SingleColorGenerator rightDownColor = new SingleColorGenerator(Color.GREEN);
		FunkyBackgroundGenerator background = new FunkyBackgroundGenerator(200, 100, 
				leftUpColor, leftDownColor, rightUpColor, rightDownColor, 0.5f);
		// 下面被註釋掉的方法四利用 FileReaderRandomBackgroundGenerator 進行設定驗證碼背景圖片
		// 第一個引數和第二個引數分別表示圖片的寬度和高度
		// 第三個引數表示圖片的資料夾,當你讀取資料夾時,會隨機取出一張圖片作為背景
//		FileReaderRandomBackgroundGenerator background = 
//				new FileReaderRandomBackgroundGenerator(
//							 200, 100, "D:\\Program Files\\apache-tomcat-6.0.20\\webapps\\image");

		// 設定單詞長度,即:單詞的位數,第二個是最大能接受字元的個數,最後一個引數是顏色
		RandomTextPaster textPaster = 
				new RandomTextPaster(new Integer(5), new Integer(5), Color.BLUE);
		// 組成驗證碼,第一引數為字型的設定,第二引數為生成的背景,第三引數為設定生成的單詞長度
		ComposedWordToImage cwti = 
				new ComposedWordToImage(fonts, background, textPaster);
		// 設定隨機取詞範圍,在這一階段一定要排除難以辨認的字元
		RandomWordGenerator words = 
				new RandomWordGenerator("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
		// 設定 GimpyFactory 類,第一個引數為驗證碼組成,第二引數是隨機取詞範圍
		GimpyFactory gimpy = new GimpyFactory(words, cwti);
		// 這個類,預設的添加了一種生成文字的工廠類
		SimpleListImageCaptchaEngine engine = new SimpleListImageCaptchaEngine();
		// 如果直接用add方法來新增,則會保留 SimpleListImageCaptchaEngine 類,預設新增的一個工廠類
		engine.setFactories(new CaptchaFactory[] { gimpy });
		// 驗證碼儲存器
		FastHashMapCaptchaStore captchaStore = new FastHashMapCaptchaStore();
		// 建立一個用來生成圖片的服務,引數如下:
		// 第一個引數是儲存器,用來儲存生成的文字,最終等待輸入驗證碼後,驗證輸入是否正確
		// 第二個引數是生成圖片的引擎
		// 第三個引數是最小保證儲存的時間,單位是秒
		// 第四個引數是最大的儲存大小,可能是生成圖片最大使用的大小
		// 第五個引數是 Captcha 在快取集合的驗證碼載入儲存數量
		DefaultManageableImageCaptchaService defaultService = new 
				DefaultManageableImageCaptchaService(captchaStore, engine, 180, 100000, 75000);
		
		return defaultService;
	}
}

d.       編寫Servlet實現類:Image.java

package sample;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.octo.captcha.service.CaptchaServiceException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*************************************************************
 * 
 * 名稱:Image
 * 型別:實現類
 * 作用:實現驗證碼生成
 * 內容:doGet()方法
 * 編寫:劉武志
 * 日期:2013-04-11
 *
 *************************************************************/

@SuppressWarnings("serial")
public class Image extends HttpServlet {
	/**
	 * 
	 * 方法名:doGet()
	 * 功    能:接受瀏覽器以Get方式訪問時進行處理
	 * 注:該方法可自動生成
	 * 
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		byte[] captchaChallengeAsJpeg = null;
		// 宣告一個 ByteArrayOutputStream 物件,用於接收輸出流
		ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
		try {
			// 返回包含分配給 Session 的唯一識別符號的字串
			String captchaId = request.getSession().getId();
			// 取得單例的 ImageCaptchaService 物件,生成一個 BufferedImage 物件
			BufferedImage challenge = SimpleCustomImageService.getInstance()
					.getImageChallengeForID(captchaId,request.getLocale());
			JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
			// 生成 jpg 格式的驗證碼圖片,儲存在 jpegOutputStream 物件中
			jpegEncoder.encode(challenge);
	} catch (IllegalArgumentException e) {
		response.sendError(HttpServletResponse.SC_NOT_FOUND);
		return;
	} catch (CaptchaServiceException e) {
		response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		return;
	}
	// 生成驗證碼圖片的byte陣列
	captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
	
	// 設定基本響應的格式
	response.setHeader("Cache-Control", "no-store");
	response.setHeader("Pragma", "no-cache");
	response.setDateHeader("Expires", 0);
	response.setContentType("image/jpeg");
	ServletOutputStream responseOutputStream = response.getOutputStream();
	// 寫入驗證碼圖片
	responseOutputStream.write(captchaChallengeAsJpeg);
	responseOutputStream.flush();
	responseOutputStream.close();
	}
}

e. 效果圖