为了控制验证码的样式,并且校验时忽略大小写,需要基于API自定义实现类。(实现方法来源于网络)
事先引入jcaptcha-1.0.jar,下面是自定义的java类文件:
/** * 自定义验证码实现类,参考Gimpy.class源码,修改后支持“忽略大小写”功能 */ public class MyGimpy extends ImageCaptcha implements Serializable { private String response; MyGimpy(String question, BufferedImage challenge, String response) { super(question, challenge); this.response = response; } public final Boolean validateResponse(final Object response) { return (null != response && response instanceof String) ? validateResponse((String) response) : Boolean.FALSE; } private final Boolean validateResponse(final String response) { // 主要改的这里 return new Boolean(response.toLowerCase().equals(this.response.toLowerCase())); } }
/** * 自定义验证码工厂:使用MyGimpy类,支持“忽略大小写” */ public class MyGimpyFactory extends ImageCaptchaFactory { private Random myRandom = new SecureRandom(); private WordToImage wordToImage; private WordGenerator wordGenerator; public static final String BUNDLE_QUESTION_KEY = Gimpy.class.getName(); public MyGimpyFactory(WordGenerator generator, WordToImage word2image) { if (word2image == null) { throw new CaptchaException("Invalid configuration" + " for a GimpyFactory : WordToImage can't be null"); } if (generator == null) { throw new CaptchaException("Invalid configuration" + " for a GimpyFactory : WordGenerator can't be null"); } wordToImage = word2image; wordGenerator = generator; } public ImageCaptcha getImageCaptcha() { return getImageCaptcha(Locale.getDefault()); } public WordToImage getWordToImage() { return wordToImage; } public WordGenerator getWordGenerator() { return wordGenerator; } public ImageCaptcha getImageCaptcha(Locale locale) { Integer wordLength = getRandomLength(); String word = getWordGenerator().getWord(wordLength, locale); BufferedImage image = null; try { image = getWordToImage().getImage(word); } catch (Throwable e) { throw new CaptchaException(e); } // 这里用我们自己写的MyGimpy ImageCaptcha captcha = new MyGimpy(CaptchaQuestionHelper.getQuestion( locale, BUNDLE_QUESTION_KEY), image, word); return captcha; } protected Integer getRandomLength() { Integer wordLength; int range = getWordToImage().getMaxAcceptedWordLength() - getWordToImage().getMinAcceptedWordLength(); int randomRange = range != 0 ? myRandom.nextInt(range + 1) : 0; wordLength = new Integer(randomRange + getWordToImage().getMinAcceptedWordLength()); return wordLength; } }
/** * 自定义验证码引擎:仿照JCaptcha2.0编写GMail验证码样式的图片引擎. * 同时使用自定义的MyGimpyFactory,支持“忽略大小写” */ public class GMailEngine extends ListImageCaptchaEngine { @Override protected void buildInitialFactories() { int minWordLength = 4; int maxWordLength = 5; int fontSize = 50; int imageWidth = 250; int imageHeight = 100; WordGenerator dictionnaryWords = new ComposeDictionaryWordGenerator(new FileDictionary("toddlist")); TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength, maxWordLength, new RandomListColorGenerator(new Color[]{new Color(23, 170, 27), new Color(220, 34, 11), new Color(23, 67, 172)}), new TextDecorator[]{} ); BackgroundGenerator background = new UniColorBackgroundGenerator(imageWidth, imageHeight, new Color(223, 221, 221)); FontGenerator font = new RandomFontGenerator(fontSize, fontSize, new Font[]{ new Font("nyala", Font.BOLD, fontSize), new Font("Bell MT", Font.PLAIN, fontSize), new Font("Credit valley", Font.BOLD, fontSize)}); ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[]{}); ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[]{}); ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[]{}); WordToImage word2image = new DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef, postDef); //这里使用自定义的验证码工厂 addFactory(new MyGimpyFactory(dictionnaryWords, word2image)); } }
/** * 保证CaptchaService单例 */ public class CaptchaServiceSingleton { private static CaptchaService captchaService=new DefaultManageableImageCaptchaService(new FastHashMapCaptchaStore(), new GMailEngine(), 180, 100000, 75000); private CaptchaServiceSingleton(){} public static BufferedImage generate(String sessionId) throws IOException { return ((AbstractManageableImageCaptchaService) captchaService).getImageChallengeForID(sessionId); } public static boolean validate(String sessionId, String authCode) { return captchaService.validateResponseForID(sessionId, authCode); } }
/** * 验证码控制器 (这里基于spring mvc) */ @Controller public class CaptchaController { /**生成*/ @RequestMapping("/captcha/generate") public void generate(HttpServletRequest request, HttpServletResponse response) throws IOException { String sessionId = request.getSession().getId(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); BufferedImage bufferedImage = CaptchaServiceSingleton .generate(sessionId); ServletOutputStream out = response.getOutputStream(); ImageIO.write(bufferedImage, "jpeg", out); out.flush(); out.close(); } /**校验*/ @RequestMapping("/captcha/validate") public void validate(HttpServletRequest request, HttpServletResponse response) throws IOException { String sessionId = request.getSession().getId(); String code = request.getParameter("code"); String validateResult = "fail"; try { validateResult = CaptchaServiceSingleton.validate(sessionId, code)?"success":"fail"; } catch (Exception e) { } PrintWriter out=response.getWriter(); out.print(validateResult); out.flush(); out.close(); } }
/** * 验证码生成与校验面向对象js */ function Captcha(){} Captcha.prototype={ init:function(image){ this.image=image; //验证码的image this.generateUrl="http://localhost:8080/test/captcha/generate";//生成路径 this.validateUrl="http://localhost:8080/test/captcha/validate";//验证路径 this.realCode=null; //真实的验证码 return this; }, /**生成*/ generate:function (){ this.realCode=null; this.image.attr("src", this.generateUrl + "?" + Math.random()); }, /**校验*/ validate:function(code){ if(code == null || code == "" || code == "undefined" ){ return false } var _this = this; if(_this.realCode!=code ){ var deferred =$.Deferred();//创建一个延迟对象,不然ajax方法return失效 $.ajax({ url:_this.validateUrl, async: false, data:"code="+code, success:function(data){ if(data=="success"){ _this.realCode=code; deferred.resolve(); }else{ _this.generate(); deferred.reject(); } }, error:function(){ _this.generate(); deferred.reject(); } }); return deferred.state() == "resolved" ? true : false; }else{ return true; } } }
//请事先引入jquery文件和自定义的captcha.js文件 <script type="text/javascript"> $(function() { var captcha = new Captcha().init($("#captchaImg")); captcha.generate(); $("#captchaImg").click(function(){ captcha.generate(); }) $("#validate_button").click(function(){ if (captcha.validate($("#captcha_code").val())) { alert("验证码正确"); } else { alert("验证码错误"); } }) }) </script> <div style="width:100%;height:600px;"> <img id="captchaImg" /></br> 验证码:<input id="captcha_code" /><br><br> <button id="validate_button">校验</button> </div>