Spring MVC 项目配置Kaptcha验证码

本文介绍如何在SpringMVC项目中配置Kaptcha验证码,包括添加依赖、配置bean信息及实现Controller、Service和Model等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring MVC 项目配置Kaptcha验证码

一般的网站注册和登录验证码都是用前端JS来实现的,只要前端验证成功就可以发送注册和登录的请求,这样如果受到来自网页和爬虫的攻击,验证码相当于形同虚设,后台服务器可能收到大量的http请求,严重影响服务器的性能。由此可见,如果由后台生成验证码之后展现给页面,页面每次的请求带上验证码信息到后台来比对会安全一些,成功再进行之后的操作,失败则返回提示信息。配置Kaptcha验证码正好可以完美达到此效果。本文介绍如何在Spring MVC项目中配置Kaptcha验证码。


Kaptcha介绍

kaptcha 是一个扩展自 simplecaptcha 的验证码库,在 Java 编程中 是一个非常实用的验证码生成工具。我们可以利用这个工具生成各种样式的验证码,因为它是可配置的,我们可以根据需求定制。

kaptcha 的工作原理是调用 com.google.code.kaptcha.servlet.KaptchaServlet ,生成一个验证码图片,响应到客户端,同时将生成的真是的验证码字符串放到 HttpSession 中。

使用kaptcha可以方便的配置

  • 验证码的字体
  • 验证码字体的大小
  • 验证码字体的字体颜色
  • 验证码内容的范围(数字,字母,中文汉字!)
  • 验证码图片的大小,边框,边框粗细,边框颜色
  • 验证码的干扰线(可以自己继承com.google.code.kaptcha.NoiseProducer写一个自定义的干扰线)
  • 验证码的样式(鱼眼样式、3D、普通模糊……当然也可以继承com.google.code.kaptcha.GimpyEngine自定义样式)

Kaptcha使用方式

添加jar包依赖

1.如果不是maven项目,则需要到官网下载jar包,然后放入项目的lib文件夹中,再导入项目。下载地址:http://code.google.com/p/kaptcha/downloads/list
2. 如果是maven项目,在pom.xml中添加dependency
<!-- kaptcha -->  
<dependency>  
    <groupId>com.google.code.kaptcha</groupId>  
    <artifactId>kaptcha</artifactId>  
    <version>2.3.2</version>  
</dependency>
本人测试maven库中几个kaptcha的jar包都下载不下来,所以在阿里的maven库找到kaptcha的dependency,亲测可以放心使用
<!-- kaptcha -->  
<dependency>  
    <groupId>com.github.penggle</groupId>  
    <artifactId>kaptcha</artifactId>  
    <version>2.3.2</version>  
</dependency>

在Spring配置文件中配置kaptcha的bean信息

<!-- google kaptcha的相关配置-->
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">  
    <property name="config">  
        <bean class="com.google.code.kaptcha.util.Config">  
        <!--通过构造函数注入属性值 -->  
        <constructor-arg type="java.util.Properties">  
            <props>  
                <!-- 验证码宽度 -->  
                <prop key="kaptcha.image.width">100</prop>   
                <!-- 验证码高度 -->  
                <prop key="kaptcha.image.height">40</prop>  
                <!-- 生成验证码内容范围 -->  
                <prop key="kaptcha.textproducer.char.string">0123456789</prop>  
                <!-- 验证码个数 -->  
                <prop key="kaptcha.textproducer.char.length">4</prop>  
                <!-- 是否有边框 -->  
                <prop key="kaptcha.border">yes</prop>  
                <!-- 边框颜色 -->  
                <prop key="kaptcha.border.color">105,179,90</prop>  
                <!-- 边框厚度 -->  
                <prop key="kaptcha.border.thickness">1</prop>  
                <!-- 验证码字体颜色 -->  
                <prop key="kaptcha.textproducer.font.color">red</prop>  
                <!-- 验证码字体大小 -->  
                <prop key="kaptcha.textproducer.font.size">40</prop>  
                <!-- 验证码所属字体样式 -->  
                <prop key="kaptcha.textproducer.font.names">BKamrnBd</prop>  
                <!-- 干扰线颜色 -->  
                <prop key="kaptcha.noise.color">blue</prop>  
                <!-- 验证码文本字符间距 -->  
                <prop key="kaptcha.textproducer.char.space">3</prop>  
            </props>  
        </constructor-arg>  
        </bean>  
    </property>  
</bean>
以上是参考配置,大家可根据自身需要进行修改,网上有好多kaptcha配置参数详解,这里就不赘述

Controller、Service、Model的实现

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

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

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 org.springframework.web.bind.annotation.RequestMethod;

import com.google.code.kaptcha.Producer;
import test.ImageCodeService;

@Controller
@RequestMapping("captcha")
public class CaptchaController {

    Logger log = LoggerFactory.getLogger(getClass());

    @Autowired Producer captchaProducer;

    @Autowired ImageCodeService imageCodeService;

    @RequestMapping(value = "/checkCaptchaCode", method = RequestMethod.GET)
    public void getCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException{
        HttpSession session = request.getSession();

        response.setDateHeader("Expires", 0);  
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");  
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");  
        response.setHeader("Pragma", "no-cache");  
        response.setContentType("image/jpeg"); 

        //利用生成的字符串构建图片
        BufferedImage bi = imageCodeService.generateImageCode(session.getId());
        ServletOutputStream out = response.getOutputStream();  
        ImageIO.write(bi, "jpg", out);  

        try {  
            out.flush();  
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
Service(生成验证码的方法执行后会将验证码以sessionId为标识存入数据库,并返回验证码图片,校验方法会根据传入的sessionId从数据库查找验证码信息,和传入的code进行比较,相同返回true)
import java.awt.image.BufferedImage;

public interface ImageCodeService {

    /**
     * 生成图片验证码并保存
     * @param id
     * @return
     */
    public BufferedImage generateImageCode(String id);

    /**
     * 后台校验注册模块图片验证码
     * @param id 唯一键,确定唯一性
     * @param code 注册页面输入的验证码
     * @return
     */
    public boolean validImageCode (String id,String code);
}
import java.awt.image.BufferedImage;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.code.kaptcha.Producer;
import test.ImageCodeMapper;
import test.ImageCode;
import test.ImageCodeService;

@Service("imageCodeService")
public class ImageCodeServiceImpl implements ImageCodeService{

    Logger log = LoggerFactory.getLogger(getClass());

    @Autowired ImageCodeMapper imageCodeMapper;

    @Autowired Producer captchaProducer;

    /**
     * 生成图片验证码并保存入数据库
     * @param sessionId
     * @return
     */
    public BufferedImage generateImageCode(String sessionId){

        //生成验证码文本
        String capText = captchaProducer.createText();  

        Date now = new Date();
        long expireLong = now.getTime() + 1000*60*5;
        now.setTime(expireLong);

        ImageCode imageCode = new ImageCode();
        imageCode.setCode(capText);
        imageCode.setExpire(0);
        imageCode.setSessionKey(sessionId);
        imageCode.setExpireTime(now);

        imageCodeMapper.insert(imageCode);
        //利用生成的字符串构建图片
        BufferedImage bi = captchaProducer.createImage(capText);

        return bi;  
    }

    /**
     * 校验图片验证码
     * @param sessionId
     * @return
     */
    public boolean validImageCode (String sessionId,String code){

        ImageCode imageCode = imageCodeMapper.selectByPrimaryKey(sessionId);
        if(imageCode != null && imageCode.getExpire() == 0){
            if(!imageCode.getCode().equals(code)){
                return false;
            }
            return new Date().getTime() < imageCode.getExpireTime().getTime();
        }

        return false;
    }
}
Model
import java.util.Date;

public class ImageCode {
    private String sessionKey;

    private Integer expire;

    private Date expireTime;

    private String code;

    public String getSessionKey() {
        return sessionKey;
    }

    public void setSessionKey(String sessionKey) {
        this.sessionKey = sessionKey == null ? null : sessionKey.trim();
    }

    public Integer getExpire() {
        return expire;
    }

    public void setExpire(Integer expire) {
        this.expire = expire;
    }

    public Date getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(Date expireTime) {
        this.expireTime = expireTime;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code == null ? null : code.trim();
    }
}

页面代码

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>验证码</title>
</head>
<body>
    <div class="proving-box clearfixed" id="imageCodeAuth">
        <div class="proving-input">
        <div class="input-box"><input type="text" id="authCode" value="图片验证码" /></div>
    </div>
    <img id="changeCaptcha" src="http://localhost:8080/captcha/checkCaptchaCode"/>
</body>
<script type="text/javascript">
$(function(){
    $('img').click(function () {//点击验证码图片,重新生成验证码  
        $(this).attr('src', '/captcha/checkCaptchaCode?' + Math.floor(Math.random()*100) );
    });         
});
</script>
</html>
至此,kaptcha的配置就完成了,页面中即可显示验证码图片

这里写图片描述

kaptcha可配置项参考

kaptcha.border  是否有边框  默认为true  我们可以自己设置yes,no  
kaptcha.border.color   边框颜色   默认为Color.BLACK  
kaptcha.border.thickness  边框粗细度  默认为1  
kaptcha.producer.impl   验证码生成器  默认为DefaultKaptcha  
kaptcha.textproducer.impl   验证码文本生成器  默认为DefaultTextCreator  
kaptcha.textproducer.char.string   验证码文本字符内容范围  默认为abcde2345678gfynmnpwx  
kaptcha.textproducer.char.length   验证码文本字符长度  默认为5  
kaptcha.textproducer.font.names    验证码文本字体样式  默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)  
kaptcha.textproducer.font.size   验证码文本字符大小  默认为40  
kaptcha.textproducer.font.color  验证码文本字符颜色  默认为Color.BLACK  
kaptcha.textproducer.char.space  验证码文本字符间距  默认为2  
kaptcha.noise.impl    验证码噪点生成对象  默认为DefaultNoise  
kaptcha.noise.color   验证码噪点颜色   默认为Color.BLACK  
kaptcha.obscurificator.impl   验证码样式引擎  默认为WaterRipple  
kaptcha.word.impl   验证码文本字符渲染   默认为DefaultWordRenderer  
kaptcha.background.impl   验证码背景生成器   默认为DefaultBackground  
kaptcha.background.clear.from   验证码背景颜色渐进   默认为Color.LIGHT_GRAY  
kaptcha.background.clear.to   验证码背景颜色渐进   默认为Color.WHITE  
kaptcha.image.width   验证码图片宽度  默认为200  
kaptcha.image.height  验证码图片高度  默认为50   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值