浅析Java验证码生成库JCaptcha

所属分类: 软件编程 / java 阅读数: 35
收藏 0 赞 0 分享

JCaptcha是非常强大的,不光是可以生成图片式的验证码,还可以生成声音式的(新浪就使用了双重验证码)。本文简单的介绍了JCaptcha库以及使用实例,下面一起来看看。

下载JCaptcha库

maven依赖如此添加:

<dependency>
      <groupId>com.octo.captcha</groupId>
      <artifactId>jcaptcha</artifactId>
      <version>1.0</version>
    </dependency>

封装了一个简单的类

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.FileReaderRandomBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomListColorGenerator;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.CaptchaEngine;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;

import java.awt.*;

/**
 * 产生验证码图片的类
 */
public class CapchaHelper {
  private static final Integer MIN_WORD_LENGTH = 4;// 验证码最小长度
  private static final Integer MAX_WORD_LENGTH = 4;// 验证码最大长度
  private static final Integer IMAGE_HEIGHT = 30;// 验证码图片高度
  private static final Integer IMAGE_WIDTH = 130;// 验证码图片宽度
  private static final Integer MIN_FONT_SIZE = 15;// 验证码最小字体
  private static final Integer MAX_FONT_SIZE = 15;// 验证码最大字体
  private static final String RANDOM_WORD = "0123456789";// 随机字符

  // 验证码随机字体
  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)
  };

  // 验证码随机颜色
  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 ListImageCaptchaEngine captchaEngine;

  public static CaptchaEngine getCaptchaEngine(final String imgPath) {
    if (captchaEngine == null) {
      synchronized (CapchaHelper.class) {
        if (captchaEngine == null && imgPath != null) {
          captchaEngine = new ListImageCaptchaEngine() {
            @Override
            protected void buildInitialFactories() {
              RandomListColorGenerator randomListColorGenerator = new RandomListColorGenerator(RANDOM_COLOR);
              BackgroundGenerator backgroundGenerator = new FileReaderRandomBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, imgPath);
              WordGenerator wordGenerator = new RandomWordGenerator(RANDOM_WORD);
              FontGenerator fontGenerator = new RandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE, RANDOM_FONT);
              TextDecorator[] textDecorator = new TextDecorator[]{};
              TextPaster textPaster = new DecoratedRandomTextPaster(MIN_WORD_LENGTH, MAX_WORD_LENGTH, randomListColorGenerator, textDecorator);
              WordToImage wordToImage = new ComposedWordToImage(fontGenerator, backgroundGenerator, textPaster);
              addFactory(new GimpyFactory(wordGenerator, wordToImage));
            }
          };
        }
      }
    }
    return captchaEngine;
  }
}

响应网页中对验正码图像的请求

可以定义一个servlet响应这个请求,如果用springMVC,也可以用某个Controller中的某个方法响应这个请求,不管怎样,都需要指定一个路径对应到servlet或controller的方法,比如路径是:”/aaa/captcha”

那么在响应对这个路径的请求的Servlet中可以这样写:

//获取验证码背景图片的路径,这路径放了很多作为背景的图像
    String captcha_backgrounds = session.getServletContext().getRealPath("/WEB-INF/img/captcha");
    CaptchaEngine ce = CapchaHelper.getCaptchaEngine(captcha_backgrounds);
    //需要admin网页中用js定时从服务端获取当前的验证码
    Captcha captcha = ce.getNextCaptcha();
    //为了验证,把captcha对象放到session中,以在客户端提交验证码时进行验证
    req.getSession().setAttribute("captcha", captcha);
    //获取验证码图片,这是未压缩的位图
    BufferedImage image = (BufferedImage) captcha.getChallenge();
    resp.setContentType("image/jpeg");
    ImageIO.write(image, "jpg", resp.getOutputStream());

如果用springMVC,就这样写:

//获取验证码背景图片的路径,这路径放了很多作为背景的图像
    String captcha_backgrounds = session.getServletContext().getRealPath("/WEB-INF/img/captcha");
    CaptchaEngine ce = CapchaHelper.getCaptchaEngine(captcha_backgrounds);
    //需要admin网页中用js定时从服务端获取当前的验证码
    Captcha captcha = ce.getNextCaptcha();
    //为了验证,把captcha对象放到session中,以在客户端提交验证码时进行验证
    session.setAttribute("captcha", captcha);
    //获取验证码图片,这是未压缩的位图
    BufferedImage image = (BufferedImage) captcha.getChallenge();
    ByteArrayOutputStream bao=new ByteArrayOutputStream();
    //应缩成jpg并写到输出流中
    ImageIO.write(image, "jpg", bao);
    return bao.toByteArray();

这两种方式,向客户端返回的都是二进制数据。

String captcha_backgrounds = session.getServletContext().getRealPath(“/WEB-INF/img/captcha”);

表示路径/WEB-INF/img/captcha下面放的是作为验证码图像的背景的多张图片,必须是jpeg,大小可能没限制,你可以自己试一下。

网页中用 <IMG> 指向这个地址

<img id="captcha" src="/captcha_img" onclick="refreshCaptchaImg()" />

js函数refreshCaptchaImg()响应图片的点击,每点击一次,就重新获取一张新的验证码图片。如何重新获取验正码图片呢?

只需改变img的src属性,但这里是每次都是用同一个地址来设置这个属性,这样不会引起真正的刷新,所以方法refreshCaptchaImg()是这样实现的:

function refreshCaptchaImg() {
      //从服务端重新下载验证码图片
      //给这个地加参数纯为了强制刷新,否则由于src指向的url地址没变,浏览器不会真正生刷新图片
      var now = new Date()
      $("#captcha").attr("src","/captcha_img?"+now.getTime());

以上就是Java中验证码生成库JCaptcha的介绍及使用,希望对大家学习java有所帮助。

更多精彩内容其他人还在看

Java的面向对象编程基本概念学习笔记整理

这篇文章主要介绍了Java的面向对象编程基本概念学习笔记整理,包括类与方法以及多态等支持面向对象语言中的重要特点,需要的朋友可以参考下
收藏 0 赞 0 分享

Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

这篇文章主要介绍了Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

基于Java实现杨辉三角 LeetCode Pascal's Triangle

这篇文章主要介绍了基于Java实现杨辉三角 LeetCode Pascal's Triangle的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中Spring获取bean方法小结

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小,需要的朋友可以参考下
收藏 0 赞 0 分享

剖析Java中的事件处理与异常处理机制

这篇文章主要介绍了Java中的事件处理与异常处理机制,讲解Java是如何对事件或者异常作出响应以及定义异常的一些方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Java的Struts2框架的结构及其数据转移方式

这篇文章主要介绍了详解Java的Struts2框架的结构及其数据转移方式,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

Java封装好的mail包发送电子邮件的类

本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
收藏 0 赞 0 分享

在Java的Struts中判断是否调用AJAX及用拦截器对其优化

这篇文章主要介绍了在Java的Struts中判断是否调用AJAX及用拦截器对其优化的方法,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

java多线程Future和Callable类示例分享

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。今天我们就来研究下Future和Callab
收藏 0 赞 0 分享
查看更多