依赖坐标:

        <dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>

参考EasyCaptcha官方文档:

https://gitcode.net/mirrors/whvcse/easycaptcha?utm_source=csdn_github_accelerator

  

先上代码:

package cn.cloud9.server.test.controller;

import cn.cloud9.server.struct.common.BaseController;
import cn.cloud9.server.struct.response.NoApiResult;
import cn.cloud9.server.struct.spring.SpringContextHolder;
import cn.cloud9.server.struct.util.IpUtil;
import cn.cloud9.server.test.model.CaptchaParam;
import com.wf.captcha.SpecCaptcha;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*; import java.awt.*;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit; /**
* @author OnCloud9
* @description 验证码测试类
* @project tt-server
* @date 2022年11月07日 下午 09:11
*/
@RestController
@RequestMapping("/test/captcha")
public class CaptchaController extends BaseController {
private static final String captchaKey = "CAPTCHA";
private static final String separator = "@";
private static final StringRedisTemplate redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
private static final ValueOperations<String, String> valOps = redisTemplate.opsForValue(); /**
* 获取验证码图片
* @param param 验证码生成参数对象
* @throws IOException IO异常
*/
@NoApiResult
@GetMapping("get")
public void createCaptcha(@ModelAttribute CaptchaParam param) throws IOException {
/* 三个参数分别为宽、高、位数 */
SpecCaptcha specCaptcha = new SpecCaptcha(param.getWidth(), param.getHeight(), param.getLength());
/* 设置字体 */
specCaptcha.setFont(new Font(param.getFontName(), param.getFontStyle(), param.getFontSize())); // 有默认字体,可以不用设置
/* 设置类型,纯数字、纯字母、字母数字混合 */
specCaptcha.setCharType(param.getCharType()); /* 设置验证码 */
final String text = specCaptcha.text().toUpperCase();
final String ipAddr = IpUtil.getIpAddr(request);
final String key = captchaKey + separator + ipAddr;
final boolean isUseRedis = param.isUseRedis();
if (isUseRedis) valOps.set(key, text, 5 * 60, TimeUnit.SECONDS);
else request.getSession().setAttribute(key, text); /* 输出验证码图片 */
final boolean isBase64 = param.isBase64();
if (isBase64) {
final String base64 = specCaptcha.toBase64();
response.getWriter().write(base64);
} else {
/* 设置请求头为输出图片类型 */
response.setContentType("image/gif");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0); /* 输出验证码图片 */
specCaptcha.out(response.getOutputStream());
}
} /**
* 验证图片验证码 (可以是验证码失效,错误,这里简单判断为true和false)
* @param verifyCode 图片验证码
* @param useRedis 是否使用Redis缓存
* @return 验证结果
*/
@PostMapping("verify")
public boolean verifyCaptcha(@RequestParam String verifyCode, @RequestParam(required = false) boolean useRedis) {
String storeCode = null;
final String ipAddr = IpUtil.getIpAddr(request);
final String key = captchaKey + separator + ipAddr;
if (useRedis) {
storeCode = valOps.get(key);
} else {
final Object attribute = request.getSession().getAttribute(key);
storeCode = Objects.isNull(attribute) ? "" : String.valueOf(attribute);
}
return verifyCode.equalsIgnoreCase(storeCode);
}
}

参数对象:

package cn.cloud9.server.test.model;

import com.wf.captcha.base.Captcha;
import lombok.Data; import java.awt.*; /**
* @author OnCloud9
* @description
* @project tt-server
* @date 2022年11月25日 下午 08:50
*/
@Data
public class CaptchaParam { /* 设置宽度,高度,码数长度 */
private int width = 200;
private int height = 80;
private int length = 6; /* 字体设置 */
private String fontName = "Verdana";
private int fontStyle = Font.PLAIN;
private int fontSize = 32; /**
* 验证码字符类型设置
* TYPE_DEFAULT = 1;
* TYPE_ONLY_NUMBER = 2;
* TYPE_ONLY_CHAR = 3;
* TYPE_ONLY_UPPER = 4;
* TYPE_ONLY_LOWER = 5;
* TYPE_NUM_AND_UPPER = 6;
*/
private int charType = Captcha.TYPE_ONLY_NUMBER; /* 是否使用base64 默认不使用 */
private boolean base64 = false; /* 是否使用Redis 默认不使用 */
private boolean useRedis = false;
}

  

我想,其实就算是前后端分离项目,也一样可以用Session存验证码的

手动设置验证码生成参数,前端投送参数来决定验证码的生成和存储

这里多加一个flag判断是否使用Redis存储,接口就更灵活些

设置为true时,可以检查是否走Redis了

测试校验接口是否走Redis

使用Base64编码:

【Java】EasyCaptcha 封装验证码接口的更多相关文章

  1. 理解Java的封装与接口

    1.封装,即保留有限的外部接口(interface),隐藏具体实施细节. 2.封装在生活中很常见.比如下面是一个充电电筒: 一个用户即使不看说明书,也可以猜到这个电筒的操作: 开关和充电.这个电筒用一 ...

  2. Java基础04 封装与接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型.对 ...

  3. Java基础04 封装与接口(转载)

    数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对 ...

  4. java Vamei快速教程04 封装和接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型.对 ...

  5. java中封装,继承,多态,接口学习总结

    ### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...

  6. C++库封装JNI接口——实现java调用c++

    1. JNI原理概述 通常为了更加灵活高效地实现计算逻辑,我们一般使用C/C++实现,编译为动态库,并为其设置C接口和C++接口.用C++实现的一个库其实是一个或多个类的简单编译链接产物.然后暴露其实 ...

  7. java基础学习总结-接口

    原文链接:http://www.cnblogs.com/xdp-gacl/p/3651121.html 一.接口的概念 JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如"金丝猴是 ...

  8. Java基础05 实施接口

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...

  9. Java命名和目录接口——JNDI

    JNDI即Java命名和目录接口(JavaNaming and Directory Interface),它属于J2EE规范范畴,是J2EE的核心技术之一,提供了一组接口.类和关于命名空间的概念.JD ...

  10. 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api

    Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...

随机推荐

  1. 我有点想用JDK17了

    大家好呀,我是summo,JDK版本升级的非常快,现在已经到JDK20了.JDK版本虽多,但应用最广泛的还得是JDK8,正所谓"他发任他发,我用Java8". 其实我也不太想升级J ...

  2. 在ftl模板中调整表格

  3. nordic——long range测试

    简介:本案例测试了long range,注意nrf52系列芯片中,部分硬件是不支持CADE的,也就是不支持long range,如nrf52832就不支持long range.同时协议栈也是部分支持, ...

  4. Base64编码和解码字符串

    Base64编码和解码字符串 package com.example.core.mydemo.cpic; import org.apache.commons.codec.binary.Base64; ...

  5. PowerBI_一分钟了解POWERBI计算组功能及作用(第一部分)

    1: X-mind&计算组(CALCULATION GROUP)介绍 1.1 什么是计算组 PowerBI的计算组功能可以显著减少必须创建的冗余度量值数,通过允许将DAX表达式定义为应用于模型 ...

  6. re.search()用法详解

    re.search() 是 Python 的正则表达式库 re 中的一个方法,用于在字符串中搜索与正则表达式模式匹配的第一个位置,并返回一个匹配对象.如果没有找到匹配项,则返回 None. 以下是 r ...

  7. 内网服务器通过单台外网服务器实现外网访问,iptables NAT

    环境: ​ servera: 外网服务器 ​ serverb: 内网服务器 servera内网网关(GATEWAY)要设置为外网IP,其IP地址作为其它内网服务器的网关 servera 内网网卡配置 ...

  8. TGI 基准测试

    本文主要探讨 TGI 的小兄弟 - TGI 基准测试工具.它能帮助我们超越简单的吞吐量指标,对 TGI 进行更全面的性能剖析,以更好地了解如何根据实际需求对服务进行调优并按需作出最佳的权衡及决策.如果 ...

  9. C#中关于 object,dynamic 一点使用心得

    首先说一下使用场景  WebAPI接口入参使用 object和 dynamic 后续解析和处理 1.object和dynamic 区别 在.NET中,object和dynamic也有一些区别: obj ...

  10. Qt中全局变量的定义和使用

    全局变量的定义 现在需要将自定义的STRParameter变量定义为全局变量,就需要新建两个文件,分别命名为"global.h"和"global.cpp" 在g ...