1、前言

kaptcha是一个非常实用的短信验证码生成工具,通过简单配置即可实现多样化的验证码。

2、引入依赖

<!--第三方验证码-->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

3、前台

假设前台调用样式如下:

<img alt="验证码" width="128" height="42"  @click="changeImage" src="项目地址/validate/captcha-image" ref="checkCode"/>

通过调用 /validate/captcha-image 接口地址获取验证码。

4、后台

4.1 controller

@RequestMapping("/captcha-image")
public void defaultKaptcha(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception{
    validateService.defaultKaptcha(httpServletRequest,httpServletResponse);
}

4.2 serviceImpl

@Autowired
private StringRedisTemplate redisTemplate; @Autowired
DefaultKaptcha defaultKaptcha; //验证码失效时间 15分钟
private static final int VALID_CODE_CACHE_EXPIRE_TIME = 900;  /**
 * 生成图片验证码
 * @param httpServletRequest request
 * @param httpServletResponse response
 */
public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)throws Exception{
    byte[] captchaChallengeAsJpeg = null;
    ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
    try {
        /*生产验证码字符串并保存到session中*/
        String createText = defaultKaptcha.createText();
        String key = String.format("login_valid_code_%s", httpServletRequest.getSession().getId());
        redisTemplate.opsForValue().set(key, createText, VALID_CODE_CACHE_EXPIRE_TIME, TimeUnit.SECONDS);
        //httpServletRequest.getSession().setAttribute("vrifyCode", createText);
        //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
        BufferedImage challenge = defaultKaptcha.createImage(createText);
        ImageIO.write(challenge, "jpg", jpegOutputStream);
    } catch (IllegalArgumentException e) {
        httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }     //定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
    captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
    httpServletResponse.setHeader("Cache-Control", "no-store");
    httpServletResponse.setHeader("Pragma", "no-cache");
    httpServletResponse.setDateHeader("Expires", 0);
    httpServletResponse.setContentType("image/jpeg");
    ServletOutputStream responseOutputStream =
    httpServletResponse.getOutputStream();
    responseOutputStream.write(captchaChallengeAsJpeg);
    responseOutputStream.flush();
    responseOutputStream.close();
}

补充:DefaultKaptcha是引入kaptcha依赖后即直接可引入的;

如上思路代码已经很清晰了,通过DefaultKaptcha创建验证码文本,然后存入redis一份,用于后面的验证使用;

注意:redis 拼接的 key 规则为 login_valid_code_ + sessionId(session id)

5、效果

前端实际应用效果:

浏览器直接调用接口效果:

6、验证

6.1 controller

从redis中取

/**
 * 验证验证码
 * @return Object
 */
@UnAuthorization
@RequestMapping(value = "code/check", method = {RequestMethod.POST})
public Object checkCode(@RequestBody @Valid CheckValidateRequest checkValidateRequest , BindingResult bindingResult, HttpServletRequest request) {
    return validateService.checkValidateCode(httpServletRequest.getSession().getId(),checkValidateRequest.getValidCode());
}

6.2 serviceImpl

/**
 * 验证短信验证码有效性
 * @param mobile 手机号码 或者 sessionId
 * @param validCode 验证码
 * @return boolean
 */
public boolean checkValidateCode(String sessionId, String validCode) {     Object iValidCodeFromRedis = cacheService.getCache(String.format("login_valid_code_%s", sessionId));
    String sValidCodeFromRedis = String.valueOf(iValidCodeFromRedis);
    if (StringUtils.isNotBlank(sValidCodeFromRedis) && validCode.equalsIgnoreCase(sValidCodeFromRedis)) {
        return true;
    }     throw new CommonException(ValidateStatusEn.CHECK_VALID_CODE_FAILED.getErrorMsg(), ValidateStatusEn.CHECK_VALID_CODE_FAILED.getErrorCode());
}

补充:通过 login_valid_code_ + sessionIdredis 中获取验证码进行校验。


我创建了一个用来记录自己学习之路的公众号,感兴趣的小伙伴可以关注一下微信公众号:niceyoo

java生成前端验证码+验证「kaptcha」的更多相关文章

  1. Java生成随机验证码

    package com.tg.snail.core.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...

  2. java生成简单验证码图片

    概要 最近项目需要用java实现输出随机验证码图片到前台,正好有机会接触下java的绘图类,完成需求后也有时间做个总结,写篇随笔记录下也希望能帮助到有同样需求的人! 需求流程图 1.生成随机数 在ja ...

  3. 如何用java生成随机验证码

     1.VerifyCode 类:   1 package com.HRuinger.enity;                          ImageIO.write(image, " ...

  4. java生成图形验证码

    效果图 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.Buf ...

  5. java生成汉字验证码

    java实现的汉字输入验证码,主要包含两个类,一个是生成验证码,一个是判断验证码输入是否正确,实现原理非常简单,将汉字和干扰线生成图片并将汉字保存到session,前台获取每次生成验证码图片并用文本框 ...

  6. java生成一次性验证码

    1.编写生成验证码的工具类: import java.awt.BasicStroke;import java.awt.Color;import java.awt.Font;import java.aw ...

  7. java生成动态验证码

    import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;impor ...

  8. java生成随机验证码图片

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; i ...

  9. Java生成验证码并进行验证(转)

    本文转自http://blog.csdn.net/worm0527/article/details/51030864 一.实现思路 使用BufferedImage用于在内存中存储生成的验证码图片 使用 ...

随机推荐

  1. BScroll使用

    当页面内容的高度超过视口高度的时候,会出现纵向滚动条:当页面内容的宽度超过视口宽度的时候,会出现横向滚动条.也就是当我们的视口展示不下内容的时候,会通过滚动条的方式让用户滚动屏幕看到剩余的内容. 话说 ...

  2. Makefile的简洁模版

    博客地址:http://www.cnblogs.com/zengjianrong/p/4184854.html 为了方便编译零碎的测试代码,在代码的存放目录编辑了一个Makefile,添加新代码文件后 ...

  3. 运维开发实践——基于Sentry搭建错误日志监控系统

    错误日志监控也可称为业务逻辑监控, 旨在对业务系统运行过程中产生的错误日志进行收集归纳和监控告警.似乎有那么点曾相识?没错... 就是提到的“APM应用性能监控”.但它又与APM不同,APM系统主要注 ...

  4. R数据挖掘 第三篇:聚类的评估(簇数确定和轮廓系数)和可视化

    在实际的聚类应用中,通常使用k-均值和k-中心化算法来进行聚类分析,这两种算法都需要输入簇数,为了保证聚类的质量,应该首先确定最佳的簇数,并使用轮廓系数来评估聚类的结果. 一,k-均值法确定最佳的簇数 ...

  5. MP3文件信息修改

    MP3文件信息 参考链接:https://www.jianshu.com/p/e368517ec7b9 总结: ID3V1在MP3文件后面;ID3V2在MP3文件前面;现在有些文件是V1的,有些文件是 ...

  6. Jackson 序列化/反序列化时忽略某属性

    https://www.iteye.com/blog/wwwcomy-2397340 博客分类: Spring jacksonread_onlyjsonignore  基于Spring MVC的RES ...

  7. 图示详解BERT模型的输入与输出

    一.BERT整体结构 BERT主要用了Transformer的Encoder,而没有用其Decoder,我想是因为BERT是一个预训练模型,只要学到其中语义关系即可,不需要去解码完成具体的任务.整体架 ...

  8. Java线程安全面试题,你真的了解吗?

    多个线程不管以何种方式访问某个类,并且在主调代码中不需要进行同步,都能表现正确的行为. 线程安全有以下几种实现方式: 不可变 不可变(Immutable)的对象一定是线程安全的,不需要再采取任何的线程 ...

  9. iOS11里判断Safari浏览器是无痕模式还是正常模式?

    var isPrivate = false; try { window.openDatabase(null, null, null, null); } catch (_) { isPrivate = ...

  10. MYSQL中IN,INSTR,FIND_IN_SET函数效率比较(转)

    今天写代码时前台传过来类似‘1,2,3,4,5,6’的字符串,这种情况直接用IN是无效的,需要把字符串分割成数组或者组装成列表,然后再利用mabatis的foreach函数 <select id ...