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中的和提交的是一致的