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。
还有一点就是此框架为伤残人士提供语音(直接传҉递҉送҉门҉http://www.ibm.com/developerworks/cn/opensource/os-cn-jcaptcha/)(哈҉哈҉哈҉,你是的八分堡)