Spring中使用Jcaptcha实现校验码验证

本文将使用Jcaptcha实现校验码验证,并演示在Spring/SpringMVC环境下的使用方法。

1. maven依赖

<dependency>
  <groupId>com.octo.captcha</groupId>
  <artifactId>jcaptcha-all</artifactId>
  <version>1.0-RC6</version>
  <exclusions>
    <exclusion>
      <groupId>quartz</groupId>
      <artifactId>quartz</artifactId>
    </exclusion>
    <exclusion>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
    </exclusion>
    <exclusion>
      <groupId>commons-pool</groupId>
      <artifactId>commons-pool</artifactId>
      </exclusion>
    <exclusion>
      <groupId>hsqldb</groupId>
      <artifactId>hsqldb</artifactId>
    </exclusion>
    <exclusion>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
    </exclusion>
    <exclusion>
      <groupId>concurrent</groupId>
      <artifactId>concurrent</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xercesImpl</artifactId>
    </exclusion>
    <exclusion>
      <groupId>xerces</groupId>
      <artifactId>xmlParserAPIs</artifactId>
    </exclusion>
  </exclusions>
</dependency>

注:请按需对需要排除的依赖进行增减

2. 需要将Jcaptcha的Bean加入Spring管理,故新增Spring-Jcaptcha的配置文件。web.xml中

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath*:applicationContext.xml
        classpath*:applicationContext-captcha.xml
    </param-value>
</context-param>

3. applicationContext-captcha.xml的内容

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
  default-lazy-init="true">

  <bean id="captchaService" class="com.octo.captcha.service.multitype.GenericManageableCaptchaService">
    <constructor-arg index="0" ref="imageEngine" />
    <constructor-arg type="int" index="1" value="180" />
    <constructor-arg type="int" index="2" value="100000" />
  </bean>

  <bean id="imageEngine" class="com.octo.captcha.engine.GenericCaptchaEngine">
    <constructor-arg index="0">
      <list>
        <ref bean="captchaFactory" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="captchaFactory" class="com.octo.captcha.image.gimpy.GimpyFactory">
    <constructor-arg>
      <ref bean="wordgen" />
    </constructor-arg>
    <constructor-arg>
      <ref bean="wordtoimage" />
    </constructor-arg>
  </bean>

  <bean id="wordgen" class="com.octo.captcha.component.word.wordgenerator.RandomWordGenerator">
    <!--可选字符-->
    <constructor-arg>
      <value>
        0123456789abcdefghijklmnopqrstuvwxyz
      </value>
    </constructor-arg>
  </bean>

  <bean id="wordtoimage" class="com.octo.captcha.component.image.wordtoimage.ComposedWordToImage">
    <constructor-arg index="0">
      <ref bean="fontGenRandom" />
    </constructor-arg>
    <constructor-arg index="1">
      <ref bean="backGenUni" />
    </constructor-arg>
    <constructor-arg index="2">
      <ref bean="decoratedPaster" />
    </constructor-arg>
  </bean>

  <bean id="fontGenRandom" class="com.octo.captcha.component.image.fontgenerator.RandomFontGenerator">
    <!--最小字体-->
    <constructor-arg index="0">
      <value>20</value>
    </constructor-arg>
    <!--最大字体-->
    <constructor-arg index="1">
      <value>20</value>
    </constructor-arg>
    <constructor-arg index="2">
      <list>
        <bean class="java.awt.Font">
          <constructor-arg index="0">
            <value>Arial</value>
          </constructor-arg>
          <constructor-arg index="1">
            <value>0</value>
          </constructor-arg>
          <constructor-arg index="2">
            <value>20</value>
          </constructor-arg>
        </bean>
      </list>
    </constructor-arg>
  </bean>

  <bean id="backGenUni" class="com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator">
    <!--背景宽度-->
    <constructor-arg index="0">
      <value>80</value>
    </constructor-arg>
    <!--背景高度-->
    <constructor-arg index="1">
      <value>32</value>
    </constructor-arg>
  </bean>

  <bean id="decoratedPaster" class="com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster">
    <!--最大字符长度-->
    <constructor-arg type="java.lang.Integer" index="0">
      <value>4</value>
    </constructor-arg>
    <!--最小字符长度-->
    <constructor-arg type="java.lang.Integer" index="1">
      <value>4</value>
    </constructor-arg>
    <!--文本颜色-->
    <constructor-arg index="2">
      <ref bean="colorGen" />
    </constructor-arg>
  <!--文本混淆-->
<constructor-arg index="3">
<list>
<!--<ref bean="baffleDecorator"/>-->
</list>
</constructor-arg>
</bean>

<bean id="baffleDecorator" class="com.octo.captcha.component.image.textpaster.textdecorator.BaffleTextDecorator">
<constructor-arg type="java.lang.Integer" index="0">
<value>1</value>
</constructor-arg>
<constructor-arg type="java.awt.Color" index="1">
<ref bean="colorWrite" />
</constructor-arg>
</bean>

<bean id="colorGen" class="com.octo.captcha.component.image.color.SingleColorGenerator">
<constructor-arg type="java.awt.Color" index="0">
<ref bean="colorDimGrey" />
</constructor-arg>
</bean>

<bean id="colorWrite" class="java.awt.Color">
<constructor-arg type="int" index="0">
<value>255</value>
</constructor-arg>
<constructor-arg type="int" index="1">
<value>255</value>
</constructor-arg>
<constructor-arg type="int" index="2">
<value>255</value>
</constructor-arg>
</bean>

<bean id="colorDimGrey" class="java.awt.Color">
<constructor-arg type="int" index="0">
<value>105</value>
</constructor-arg>
<constructor-arg type="int" index="1">
<value>105</value>
</constructor-arg>
<constructor-arg type="int" index="2">
<value>105</value>
</constructor-arg>
</bean>
</beans>

4. 服务端生成校验码

package personal.hutao.captcha;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.octo.captcha.service.image.ImageCaptchaService;

@Controller
@RequestMapping("/captcha")
public class JcaptchaImageCreater {

  private Logger logger = LoggerFactory.getLogger(getClass());

  @Autowired
  private ImageCaptchaService imageCaptchaService;

  @RequestMapping
  public void handleRequest(HttpServletRequest request, HttpServletResponse response) {
    try {
      ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
      String captchaId = request.getSession().getId();
      BufferedImage challenge = imageCaptchaService.getImageChallengeForID(captchaId, request.getLocale());

      response.setHeader("Cache-Control", "no-store");
      response.setHeader("Pragma", "no-cache");
      response.setDateHeader("Expires", 0L);
      response.setContentType("image/jpeg");

      ImageIO.write(challenge, "jpeg", jpegOutputStream);
      byte[] captchaChallengeAsJpeg = jpegOutputStream.toByteArray();

      ServletOutputStream respOs = response.getOutputStream();
      respOs.write(captchaChallengeAsJpeg);
      respOs.flush();
      respOs.close();
    } catch (IOException e) {
      logger.error("generate captcha image error: {}", e.getMessage());
    }
  }

}

5. 页面调用

<input type="text" id="captcha" name="captcha" maxlength="4" />
<img src="captcha" onclick="this.src=‘captcha?d=‘+new Date().getTime()"/>

如图:

6. 提交登录表单后,校验

package personal.hutao.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.octo.captcha.service.image.ImageCaptchaService;

@RequestMapping("/login")
@Controller
public class LoginController {

  @Autowired
  private ImageCaptchaService imageCaptchaService;

  @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
  @ResponseBody
  public Boolean login(String username, String password, String captcha, HttpServletRequest request) {
    Boolean result = Boolean.FALSE;

    Boolean isResponseCorrect = imageCaptchaService.validateResponseForID(request.getSession().getId(), captcha);
    if (isResponseCorrect) {
      // 继续校验用户名密码等..
    }

    return result;
  }

}
时间: 2024-10-07 15:33:25

Spring中使用Jcaptcha实现校验码验证的相关文章

SpringMVC中使用Jcaptcha实现校验码验证

SpringMVC中使用Jcaptcha实现校验码验证:http://www.tuicool.com/articles/rMzAFj 本文将使用Jcaptcha实现校验码验证,并演示在Spring/SpringMVC环境下的使用方法. 1. maven依赖 注:请按需对需要排除的依赖进行增减 <dependency> <groupId>com.octo.captcha</groupId> <artifactId>jcaptcha-all</artifa

计组_海明校验码

原理: 在数据中加入几个校验码,并把数据的每一个二进制位分配在几个奇偶校验组中. 设:校验位的个数为r,能表示2^r个信息,1个表示“没错误”, 2^r -1个指出错误发生在哪一位. k= 2^r –1-r个信息可用于纠正数据位. 2^r≥k+r+1 若要检测并纠正一位错,同时发现两位错,r,k应满足下列关系: 2^r-1≥k+r      (见表3.8) 校验位和数据位是如何排列的 校验位排列在  2^(i–1) (i =0,1,2,…)的位置上 例:有一个编码 为D4D3D2D1,由此生成一

Spring 4 MVC 表单校验资源处理(带源码)

[本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看] [翻译 by 明明如月 QQ 605283073] 上一篇:Spring 4 MVC HelloWorld 纯注解方式(带源码) 下一篇文章:Spring 4 MVC 视图解析器(XML JSON PDF等) 纯注解 #项目下载地址:http://websystique.com/?smd_process_download=1&download_id=1258# 本文我们将学习使用Spring 表单标签( Spring

第5章—构建Spring Web应用程序—关于spring中的validate注解后台校验的解析

关于spring中的validate注解后台校验的解析 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间.成本.质量的博弈中必然会落后.所以把校验层抽象出来是必然的结果,下面说下几种解决方案. 1.简单的校验Demo 依赖: <dependency> <groupId>javax.validation</groupId> <

Spring中@Transactional事务回滚实例及源码

一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除某个部门的时候,假设我们默认删除对应的成员.但是在执行的时候可能会出现这种情况,我们先删除部门,再删除成员,但是部门删除成功了,删除成员的时候出异常了.这时候我们希望如果成员删除失败了,之前删除的部门也取消删除.这种场景就可以使用@Transactional事物回滚. 二.checked异常和unc

Redis源码中的CRC校验码(crc16、crc64)原理浅析

在阅读Redis源码的时候,看到了两个文件:crc16.c.crc64.c.下面我抛砖引玉,简析一下原理. CRC即循环冗余校验码,是信息系统中一种常见的检错码.大学课程中的"计算机网络"."计算机组成"等课程中都有提及.我们可能都了解它的数学原理,在试卷上手工计算一个CRC校验码,并不是难事.但是计算机不是人,现实世界中的数学原理需要转化为计算机算法才能实现目的.实际上作为计算机专业背景人并不会经常使用或接触到CRC的计算机算法实现的原理,通常是电子学科背景的人士

Spring中@Transactional事务回滚(含实例详细讲解,附源码)

原文出处: 小宝鸽 一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除某个部门的时候,假设我们默认删除对应的成员.但是在执行的时候可能会出现这种情况,我们先删除部门,再删除成员,但是部门删除成功了,删除成员的时候出异常了.这时候我们希望如果成员删除失败了,之前删除的部门也取消删除.这种场景就可以使用@Transactional事物回滚. 二.che

Spring中Bean命名源码分析

Spring中Bean命名源码分析 一.案例代码 首先是demo的整体结构 其次是各个部分的代码,代码本身比较简单,不是我们关注的重点 配置类 /** * @Author Helius * @Create 2019-10-25-20:16 */ @Configuration @ComponentScan(basePackages = {"service"}) public class SpringConfiguration { } 接口的实现类 public interface Use

CRC校验码的verilog实现与仿真结果

循环冗余校验码(CRC)的基本原理是: 将被处理的报文比特序列当做一个二进制多项式A(x)的系数,(任意一个由二进制位串组成的代码都可以和一个系数仅为'0'和'1'取值的多项式一一对应.例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111),该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它副到原始的报文A(x)后面形成新的报