java-Kaptcha生成验证码图片(五分钟学会)

验证码的作用是防止恶意破解密码、刷票、论坛灌水、刷页等。
如下是一个实际例子:


image.png

而Kaptcha则是生成这样的验证码图片的一个功能强大的工具包。
然后开始说这个Kaptcha要怎么使用。

导包

<dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>kaptcha</artifactId>
    <version>0.0.9</version>
</dependency>

添加配置

package io.renren.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;


/**
 * 生成验证码配置
 *
 * @author Mark sunlightcs@gmail.com
 */
@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha producer() {
        Properties properties = new Properties();
        properties.put("kaptcha.border", "no");
        properties.put("kaptcha.textproducer.font.color", "black");
        properties.put("kaptcha.textproducer.char.space", "6");
        properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

然后上面的几个配置自己看着写。这个kaptcha有多种配置可以改的,我贴出来:


kaptcha可选参数

可选参数2

反正我用起来也没那么麻烦,其实默认配置差不多就满足了,自己看心意调吧。

在接口中使用

以上两步配置就完了,接下来该使用了。
其实就是把它配置成一个可以前端访问的接口了。

存session中

    @Autowired
    private Producer producer;
    
    @GetMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response,HttpServletRequest request) throws ServletException,IOException{
        response.setHeader("Cache-Control", "no-store,no-cache");
        response.setContentType("image/jpeg");
        //生成文字验证码
        String text=producer.createText();
        //生成图片验证码
        BufferedImage image=producer.createImage(text);
        //保存验证码到session
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        ServletOutputStream out=response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        //用到IO工具包控制开关
        IOUtils.closeQuietly(out);
        
    }

存数据库

存session就不多说了,但是我使用的时候是存数据库的,个人感觉存数据库可以灵活设置过期时间。(好吧,我承认这个做法是当时没想到session)。反正现在是实现了,所以也记录下来吧。
因为存数据库所以肯定要先建表:


表结构

如图,很简单的表结构:uuid是主键,code是验证码。expire_time是过期时间。
然后每次生成验证码,需要一个参数(说是uuid其实用的时候就是一个id的作用)。会将这个uuid当做表的主键,然后code和过期时间一起存到数据库。
在登录的时候先做校验,判断这个uuid的code和输入的验证码是否一样,是的话验证成功,并且删除这条记录。不是的话返回验证码错误。
大概逻辑就是这样,我一步步贴代码:
这个是将验证码保存到数据库和校验验证码的两个方法

    @Autowired
    private Producer producer;
    
    /**
     * 生成验证码并且将这条记录保存到数据库
     */
    @Override
    public BufferedImage getCaptcha(String uuid) {
        if(StringUtils.isBlank(uuid)){
            throw new RRException("uuid不能为空");
        }
        //生成文字验证码
        String code = producer.createText();
        //这里是生成实体,然后存入数据库,看逻辑就行,别原封不动用代码
        SysCaptchaEntity captchaEntity = new SysCaptchaEntity();
        captchaEntity.setUuid(uuid);
        captchaEntity.setCode(code);
        //3分钟后过期.这个用到了自己封装的日期处理方法
        captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 3));
        this.save(captchaEntity);
        return producer.createImage(code);
    }
    
    
    /**
     * 验证验证码是否正确
     */
    @Override
    public boolean validate(String uuid, String code) {
        SysCaptchaEntity captchaEntity = this.getOne(new QueryWrapper<SysCaptchaEntity>().eq("uuid", uuid));
        if(captchaEntity == null){
            return false;
        }

        //删除验证码
        this.removeById(uuid);

        if(captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){
            return true;
        }

        return false;
    }

这个是正式调用生成验证码的方法:

    /**
     * 验证码
     */
    @ApiOperation("获取验证码")
    @RequestMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response, @ApiParam(name="uuid",value="随机字符串") String uuid)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //获取图片验证码
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

这个是在登录的时候验证验证码的两行代码:

boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
        if(!captcha){
            return R.error("验证码不正确");
        }

至此,这个生成验证码的功能完成了,顺便附上截图:


postman自测

网页测试

本篇笔记就到这里,如果稍微帮到你了记得点个喜欢点个关注。也祝大家工作顺顺利利,生活愉快!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,849评论 0 5
  • 1.JVM 堆内存和非堆内存 堆和非堆内存按照官方的说法:“Java 虚拟机具有一个堆(Heap),堆是运行时数据...
    yanzhu728阅读 913评论 0 0
  • 这几天不知怎么有点倦怠了,因为之前有停了一天,因为手机忘在外面了。 我最近生活的确有些改变。本来国庆准备出去学习,...
    何偀阅读 209评论 1 0
  • 身体痛了,我们能够感知到。 可是心疼了,你能感受到吗? 你真的了解自己当下的情绪吗?...
    胖粽子皮阅读 678评论 3 7
  • 1、电影行业背景及前景: 按照目前院线电影上映的票房情况来预测,您投资10万,这四种收益都到手您可以直接在二线城市...
    银狐影视谈电影世界阅读 5,812评论 0 0