导读:
jcaptcha是一个开源的用来生成图形验证码的Java开源组件,使用起来也是非常的简单方便。不过,很多网友抱怨该组件默认的图片比较大,影响网页的美观。由于代码过于简单,以至于找不到地方修改。由于tycho(我正在开发的程序)也需要利用该组件生成验证码,所以简单地研究了一下。发现 jcapthca是非常强大的,不光是可以生成图片式的验证码,还可以生成声音式的(新浪就使用了双重验证码)。大家可以到这里下载,并导入到你的工程。
若要利用jcaptcha生成自定义样式的验证码,首先需要为其创建一个验证码引擎,或者说验证码方案类。如下:
public classMyImageCaptchaEngine
extendsListImageCaptchaEngine {
protectedvoidbuildInitialFactories(){
// 随机生成的字符
WordGenerator wgen = newRandomWordGenerator(
"abcdefghijklmnopqrstuvwxyz123456789");
RandomRangeColorGenerator cgen =
newRandomRangeColorGenerator(
newint[]{0, 100}, newint[]{0, 100},
newint[]{0, 100});
// 文字显示的个数
TextPaster textPaster = newRandomTextPaster( new Integer(6),
new Integer(6), cgen, true);
// 图片的大小
BackgroundGenerator backgroundGenerator =
newFunkyBackgroundGenerator(
new Integer(150), new Integer(50));
// 字体格式
Font[]fontsList = new Font[]{
new Font("Arial", 0, 10),
new Font("Tahoma", 0, 10), new Font("Verdana", 0, 10), };
// 文字的大小
FontGenerator fontGenerator =
newRandomFontGenerator( new Integer(15),
new Integer(30), fontsList);
WordToImage wordToImage = newComposedWordToImage(fontGenerator,
backgroundGenerator, textPaster);
this.addFactory( newGimpyFactory(wgen, wordToImage));
}
}
上面的自定义验证码引擎继承了ListImageCaptchaEngine类,那么它将会生成一个彩色的验证码。当然,你还可以继承其它的类来生成不同的验证码,如:声音格式的验证码。具体请参照官方网站。
接下来,我们要为其定义一个单例类的全局对象,并在构造方法中注入我们的引擎。如下:
public classCaptchaServiceSingleton {
private staticDefaultManageableImageCaptchaService instance =
newDefaultManageableImageCaptchaService(
newFastHashMapCaptchaStore(),
newMyImageCaptchaEngine(),
180,
100000,
75000);
public staticImageCaptchaService getInstance(){
returninstance;
}
}
为什么要创建为单例的?当然,你可以不创建为单例类,但是你会发现,每次打开有验证码的画面时,验证码显示的都很慢,那是因为创建该对象的实例时,需要在内存中创建背景图像、描点、边框等等工作的原因。而创建一次后,图片框架就不需要再次创建了,以后每次调用该实例时,只是生成随机字符并嵌入图片中即可。
接下来要做的就是,生成一个servlet,用来和前台页面交互,如下:
public classImageCaptchaServlet extendsHttpServlet {
publicvoidinit(ServletConfig servletConfig)
throwsServletException {
super.init(servletConfig);
}
// 复写doGet
protectedvoiddoGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throwsServletException, IOException{
byte[]captchaChallengeAsJpeg = null;
ByteArrayOutputStreamjpegOutputStream =
new ByteArrayOutputStream();
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
jcaptcha是一个开源的用来生成图形验证码的Java开源组件,使用起来也是非常的简单方便。不过,很多网友抱怨该组件默认的图片比较大,影响网页的美观。由于代码过于简单,以至于找不到地方修改。由于tycho(我正在开发的程序)也需要利用该组件生成验证码,所以简单地研究了一下。发现 jcapthca是非常强大的,不光是可以生成图片式的验证码,还可以生成声音式的(新浪就使用了双重验证码)。大家可以到这里下载,并导入到你的工程。
若要利用jcaptcha生成自定义样式的验证码,首先需要为其创建一个验证码引擎,或者说验证码方案类。如下:
public classMyImageCaptchaEngine
extendsListImageCaptchaEngine {
protectedvoidbuildInitialFactories(){
// 随机生成的字符
WordGenerator wgen = newRandomWordGenerator(
"abcdefghijklmnopqrstuvwxyz123456789");
RandomRangeColorGenerator cgen =
newRandomRangeColorGenerator(
newint[]{0, 100}, newint[]{0, 100},
newint[]{0, 100});
// 文字显示的个数
TextPaster textPaster = newRandomTextPaster( new Integer(6),
new Integer(6), cgen, true);
// 图片的大小
BackgroundGenerator backgroundGenerator =
newFunkyBackgroundGenerator(
new Integer(150), new Integer(50));
// 字体格式
Font[]fontsList = new Font[]{
new Font("Arial", 0, 10),
new Font("Tahoma", 0, 10), new Font("Verdana", 0, 10), };
// 文字的大小
FontGenerator fontGenerator =
newRandomFontGenerator( new Integer(15),
new Integer(30), fontsList);
WordToImage wordToImage = newComposedWordToImage(fontGenerator,
backgroundGenerator, textPaster);
this.addFactory( newGimpyFactory(wgen, wordToImage));
}
}
上面的自定义验证码引擎继承了ListImageCaptchaEngine类,那么它将会生成一个彩色的验证码。当然,你还可以继承其它的类来生成不同的验证码,如:声音格式的验证码。具体请参照官方网站。
接下来,我们要为其定义一个单例类的全局对象,并在构造方法中注入我们的引擎。如下:
public classCaptchaServiceSingleton {
private staticDefaultManageableImageCaptchaService instance =
newDefaultManageableImageCaptchaService(
newFastHashMapCaptchaStore(),
newMyImageCaptchaEngine(),
180,
100000,
75000);
public staticImageCaptchaService getInstance(){
returninstance;
}
}
为什么要创建为单例的?当然,你可以不创建为单例类,但是你会发现,每次打开有验证码的画面时,验证码显示的都很慢,那是因为创建该对象的实例时,需要在内存中创建背景图像、描点、边框等等工作的原因。而创建一次后,图片框架就不需要再次创建了,以后每次调用该实例时,只是生成随机字符并嵌入图片中即可。
接下来要做的就是,生成一个servlet,用来和前台页面交互,如下:
public classImageCaptchaServlet extendsHttpServlet {
publicvoidinit(ServletConfig servletConfig)
throwsServletException {
super.init(servletConfig);
}
// 复写doGet
protectedvoiddoGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throwsServletException, IOException{
byte[]captchaChallengeAsJpeg = null;
ByteArrayOutputStreamjpegOutputStream =
new ByteArrayOutputStream();
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