public abstract class AbstractCaptchaEngine extends ImageCaptchaEngine { private List<CaptchaFactory> factories = new ArrayList<CaptchaFactory>(); private Random myRandom = new SecureRandom(); public AbstractCaptchaEngine(String path) { buildInitialFactories(path); checkFactoriesSize(); } protected abstract void buildInitialFactories(String path); public boolean addFactory(ImageCaptchaFactory factory) { return this.factories.add(factory); } public void addFactories(ImageCaptchaFactory[] factories) { for (int i = 0; i < factories.length; i++) this.factories.add(factories[i]); } public CaptchaFactory[] getFactories() { return (CaptchaFactory[]) (CaptchaFactory[]) this.factories.toArray(new CaptchaFactory[this.factories.size()]); } public void setFactories(CaptchaFactory[] factories) throws CaptchaEngineException { if ((factories == null) || (factories.length == 0)) { throw new CaptchaEngineException("impossible to set null or empty factories"); } List<CaptchaFactory> tempFactories = new ArrayList<CaptchaFactory>(); for (int i = 0; i < factories.length; i++) { if (ImageCaptchaFactory.class.isAssignableFrom(factories[i].getClass())) { throw new CaptchaEngineException("This factory is not an image captcha factory " + factories[i].getClass()); } tempFactories.add(factories[i]); } this.factories = tempFactories; } public ImageCaptchaFactory getImageCaptchaFactory() { //nextInt(n)是從0到n的隨機數(隨機獲取一個) return (ImageCaptchaFactory) this.factories.get(this.myRandom.nextInt(this.factories.size())); } @Override public ImageCaptcha getNextImageCaptcha() { return getImageCaptchaFactory().getImageCaptcha(); } @Override public ImageCaptcha getNextImageCaptcha(Locale locale) { //Local那個 return getImageCaptchaFactory().getImageCaptcha(locale); } private void checkFactoriesSize() { if (this.factories.size() == 0) throw new CaptchaException("This gimpy has no factories. Please initialize it properly with the buildInitialFactory() called by the constructor or the addFactory() mehtod later!"); } }
/** * 仿照JCaptcha2.0編寫GMail驗證碼樣式的圖片引擎. * * @author can */ public class GMailEngine extends AbstractCaptchaEngine { public static final String IMAGE_CAPTCHA_KEY = "imageCaptcha";// ImageCaptcha對象存放在Session中的key public static final String CAPTCHA_INPUT_NAME = "j_captcha";// 驗證碼輸入表單名稱 //public static final String CAPTCHA_IMAGE_URL = "/captcha";// 驗證碼圖片URL private static final Integer MIN_WORD_LENGTH = 4;// 驗證碼最小長度 private static final Integer MAX_WORD_LENGTH = 4;// 驗證碼最大長度 private static final Integer IMAGE_HEIGHT = 26;// 驗證碼圖片高度 private static final Integer IMAGE_WIDTH = 70;// 驗證碼圖片寬度 private static final Integer MIN_FONT_SIZE = 15;// 驗證碼最小字體 private static final Integer MAX_FONT_SIZE = 15;// 驗證碼最大字體 private static final String RANDOM_WORD = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&";// 隨機字符 //private static final String IMAGE_PATH = "com/rekoe/cms/captcha/";// 隨機背景圖片路徑 // 驗證碼隨機顏色 private static final Color[] RANDOM_COLOR = new Color[] { new Color(255, 255, 255), new Color(255, 220, 220), new Color(220, 255, 255), new Color(220, 220, 255), new Color(255, 255, 220), new Color(220, 255, 220) }; // 驗證碼隨機字體 private static final Font[] RANDOM_FONT = new Font[] { new Font("nyala", Font.BOLD, MIN_FONT_SIZE), new Font("Arial", Font.BOLD, MIN_FONT_SIZE), new Font("Bell MT", Font.BOLD, MIN_FONT_SIZE), new Font("Credit valley", Font.BOLD, MIN_FONT_SIZE), new Font("Impact", Font.BOLD, MIN_FONT_SIZE) }; public GMailEngine(String path) { super(path); } /** * can *TODO:構建初始化工廠 * 2015年3月19日 */ @Override protected void buildInitialFactories(String path) { //驗證碼隨機色 RandomListColorGenerator randomListColorGenerator = new RandomListColorGenerator(RANDOM_COLOR); //隨機字符集 WordGenerator wordGenerator = new RandomWordGenerator(RANDOM_WORD); //干擾設置,new LineTextDecorator(new Integer(1),Color.WHITE) TextDecorator[] textDecorator = new TextDecorator[] {new BaffleTextDecorator( new Integer(1),randomListColorGenerator)}; //字體大小從(MIN_FONT_SIZE到MAX_FONT。隨機字體 FontGenerator fontGenerator = new RandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE, RANDOM_FONT); //背景 BackgroundGenerator backgroundGenerator = new FileReaderRandomBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, path); //字符長度變化從MIN_WORD_LENGTH到MAX_WORD_LENGTH,顏色隨機集合, TextPaster textPaster = new DecoratedRandomTextPaster(MIN_WORD_LENGTH, MAX_WORD_LENGTH, randomListColorGenerator, textDecorator); // 生成 WordToImage wordToImage = new ComposedWordToImage ( fontGenerator, backgroundGenerator, textPaster ); //放入工廠 addFactory(new GimpyFactory(wordGenerator, wordToImage)); } }
public Object captcha(HttpServletRequest request) {//獲取驗證碼,Object表明image // 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 // request.getLocale()本地化,肯定是哪一個工廠,不҉同҉國҉家҉使҉用҉字҉符҉不҉一҉樣҉ String captchaId = request.getSession(true).getId(); return imageCaptchaService.getChallengeForID(captchaId, request.getLocale()); } //調用××××××××××××××××××××××××××根據瀏覽器輸入的驗證碼,判斷是否正確, boolean isRight = imageCaptchaService.validateResponseForID(sessionID,captchaString );
好吧,最後貢獻下,JCaptcha源碼(密҉碼҉:24d6),按照源碼採用策略模式的方式,徹底能夠訂製本身專屬的JCaptcha。 java
還有一點就是此框架爲傷殘人士提供語音(直接傳҉遞҉送҉門҉http://www.ibm.com/developerworks/cn/opensource/os-cn-jcaptcha/)(哈҉哈҉哈҉,你是的八分堡) 瀏覽器