jcaptcha验证码使用(一)
jcaptcha使用默认样式生成的验证码比较难以识别,所以需要自定义验证码的样式,包括,背景色、背景大小、字体、字体大小、生成的字符数等。相对与kaptcha比较复杂。
创建一个JavaWeb工程,引入相关依赖jar包
创建一个jcaptcha单例的Service类,这里是设置验证码样式的关键部分
package cn.util; import java.awt.Font; import com.octo.captcha.CaptchaFactory; import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator; import com.octo.captcha.component.image.color.RandomRangeColorGenerator; 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.FileDictionary; import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator; import com.octo.captcha.engine.GenericCaptchaEngine; import com.octo.captcha.image.gimpy.GimpyFactory; import com.octo.captcha.service.image.ImageCaptchaService; import com.octo.captcha.service.multitype.GenericManageableCaptchaService; public class CaptchaServiceSingleton { private static ImageCaptchaService service = null; public static ImageCaptchaService getService(){ if(service == null) service = generatorCaptchaService(); return service; } /** * 根据SpringBean的配置文件编写的代码实现 * */ public static ImageCaptchaService generatorCaptchaService(){ //生成随机颜色,参数分别表示RGBA的取值范围 RandomRangeColorGenerator textColor = new RandomRangeColorGenerator(new int[]{0,255},new int[]{0,180},new int[]{0,210},new int[]{255,255}); //随机文字多少和颜色,参数1和2表示最少生成多少个文字和最多生成多少个 RandomTextPaster randomTextPaster = new RandomTextPaster(4, 5, textColor,true); //生成背景的大小这里是宽85高40的图片,也可以设置背景颜色和随机背景颜色,这里使用默认的白色 UniColorBackgroundGenerator colorbgGen = new UniColorBackgroundGenerator(85,40); //随机生成的字体大小和字体类型,参数1和2表示最小和最大的字体大小,第三个表示随机的字体 RandomFontGenerator randomFontGenerator = new RandomFontGenerator(20, 25, new Font[]{new Font("Arial", 0, 10),new Font("Tahoma",0,10)}); //结合上面的对象构件一个从文本生成图片的对象 ComposedWordToImage cwti = new ComposedWordToImage(randomFontGenerator,colorbgGen,randomTextPaster); //随机文本的字典,这里是使用jcaptcha-1.0-all.jar中的文本字典,字典名称为toddlist.properties ComposeDictionaryWordGenerator cdwg = new ComposeDictionaryWordGenerator(new FileDictionary("toddlist")); GimpyFactory gf = new GimpyFactory(cdwg, cwti); GenericCaptchaEngine gce = new GenericCaptchaEngine(new CaptchaFactory[]{gf}); //返回一个Service对象,这里180是验证码存在的时间,单位是秒,200000是最大存储大小 return new GenericManageableCaptchaService(gce,180,200000,75000); } }
创建一个生成验证码的Servlet
package cn.servlet; 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.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; import cn.util.CaptchaServiceSingleton; public class CustomServlet extends HttpServlet { private static final long serialVersionUID = 169310818225761427L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { byte[] captChallengeAsJpeg = null; ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); String captchaId = req.getSession().getId(); BufferedImage challenge = CaptchaServiceSingleton.getService().getImageChallengeForID(captchaId,req.getLocale()); JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream); jpegEncoder.encode(challenge); captChallengeAsJpeg = jpegOutputStream.toByteArray(); resp.setHeader("Cache-Control", "no-store"); resp.setHeader("Pragma", "no-cache"); resp.setDateHeader("Expires", 0); resp.setContentType("image/jpeg"); ServletOutputStream respOutputStream = resp.getOutputStream(); respOutputStream.write(captChallengeAsJpeg); respOutputStream.flush(); respOutputStream.close(); } }
在web.xml中注册这个Servlet
<servlet> <servlet-name>generateValidateCode</servlet-name> <servlet-class>cn.servlet.CustomServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>generateValidateCode</servlet-name> <url-pattern>/cgvc</url-pattern> </servlet-mapping>
创建html页面,引入jquery.js文件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <script type="text/javascript" src="statics/js/jquery-1.8.3.min.js"></script> <script type="text/javascript"> //验证码刷新功能 function refreshCaptcha() { //Math.floor();向下取整 //jQuery效果,fadeIn() 方法使用淡入效果来显示被选元素,假如该元素是隐藏的。 $('#vcode').hide().attr( 'src', 'cgvc?'+ Math.floor(Math.random() * 100)).fadeIn(); } </script> <body> <form action="valiServlet" method="post"> <input type="text" name="customgvc"> <img onclick="refreshCaptcha()" id="vcode" title="点击更换" alt="验证图片" style="vertical-align: middle;" src="cgvc" height="30" width="80"> <input type="submit" value="提交"> </form> </body> </html>
编写一个验证Servlet并在web.xml中注册。(success.html和fail.html就不创建了)
package cn.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.util.CaptchaServiceSingleton; public class ValidateServlet extends HttpServlet { private static final long serialVersionUID = -7173743572400866269L; @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String captchaId = req.getSession().getId(); String validateCode = req.getParameter("customgvc"); boolean validateResult = CaptchaServiceSingleton.getService().validateResponseForID(captchaId, validateCode); if(validateResult) resp.sendRedirect("success.html"); else resp.sendRedirect("fail.html"); } }
<servlet> <servlet-name>validatServlet</servlet-name> <servlet-class>cn.servlet.ValidateServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>validatServlet</servlet-name> <url-pattern>/valiServlet</url-pattern> </servlet-mapping>
输入验证码点击提交,看是否可以验证通过,如果一切正常的话Session中的和提交的是一致的