浅析Java验证码生成库JCaptcha

 更新时间:2016年07月27日 14:49:18   投稿:daisy  
JCaptcha 是一个用来生成验证码的开源Java类库,使用起来也是非常的简单方便。本文通过代码实例介绍了JCaptcha类库。

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有所帮助。

相关文章

  • 浅谈JVM系列之JIT中的Virtual Call

    浅谈JVM系列之JIT中的Virtual Call

    什么是Virtual Call?Virtual Call在java中的实现是怎么样的?Virtual Call在JIT中有没有优化?所有的答案看完这篇文章就明白了。
    2021-06-06
  • Java中反射reflect的基础知识讲解

    Java中反射reflect的基础知识讲解

    这篇文章主要介绍了Java中反射reflect的基础知识讲解,Java中的反射,它算是Java当中非常底层的一个技术,平时我们我们用得不多,实际上它也的确非常复杂同时也难以理解,但是涉及到底层的东西Java都给我们封装好了,我们直接拿来调用即可,需要的朋友可以参考下
    2023-10-10
  • Mybatis-Plus接口BaseMapper与Services使用详解

    Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 编写Java代码制造一个内存溢出的情况

    编写Java代码制造一个内存溢出的情况

    这篇文章主要介绍了编写Java代码制造一个内存溢出的情况,或许这种有意制造能够更好地帮助理解Java中的内存溢出情况XD 需要的朋友可以参考下
    2015-07-07
  • Java 装箱与拆箱详解及实例代码

    Java 装箱与拆箱详解及实例代码

    这篇文章主要介绍了Java 装箱与拆箱详解及实例代码的相关资料,这里对java 的装箱及拆箱进行了基本概念详解及简单使用,需要的朋友可以参考下
    2017-01-01
  • java动态线程池的简单实现思路

    java动态线程池的简单实现思路

    本文主要介绍了java 动态线程池的简单实现思路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • springboot使用DynamicDataSource动态切换数据源的实现过程

    springboot使用DynamicDataSource动态切换数据源的实现过程

    这篇文章主要给大家介绍了关于springboot使用DynamicDataSource动态切换数据源的实现过程,Spring Boot应用中可以配置多个数据源,并根据注解灵活指定当前使用的数据源,需要的朋友可以参考下
    2023-08-08
  • 解决java文件流处理异常 mark/reset not supported问题

    解决java文件流处理异常 mark/reset not supported问题

    这篇文章主要介绍了解决java文件流处理异常 mark/reset not supported问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java中过滤器 (Filter) 和 拦截器 (Interceptor)的使用

    Java中过滤器 (Filter) 和 拦截器 (Interceptor)的使用

    这篇文章主要介绍了Java中过滤器 (Filter) 和 拦截器 (Interceptor)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 一文带你弄懂Maven拉包(拉取依赖包)原理

    一文带你弄懂Maven拉包(拉取依赖包)原理

    业务需求开发的时候,我们总是会遇到拉不到依赖包的情况,此时如果不清楚 Maven 拉取依赖包的原理,那么很可能找不到问题所在,今天小编就带大家了解下 Maven 拉包的原理,让你在遇到问题的时候能快速解决,需要的朋友可以参考下
    2023-07-07

最新评论