【Java】EasyCaptcha 封装验证码接口
依赖坐标:
<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 封装验证码接口的更多相关文章
- 理解Java的封装与接口
1.封装,即保留有限的外部接口(interface),隐藏具体实施细节. 2.封装在生活中很常见.比如下面是一个充电电筒: 一个用户即使不看说明书,也可以猜到这个电筒的操作: 开关和充电.这个电筒用一 ...
- Java基础04 封装与接口
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型.对 ...
- Java基础04 封装与接口(转载)
数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对 ...
- java Vamei快速教程04 封装和接口
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型.对 ...
- java中封装,继承,多态,接口学习总结
### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...
- C++库封装JNI接口——实现java调用c++
1. JNI原理概述 通常为了更加灵活高效地实现计算逻辑,我们一般使用C/C++实现,编译为动态库,并为其设置C接口和C++接口.用C++实现的一个库其实是一个或多个类的简单编译链接产物.然后暴露其实 ...
- java基础学习总结-接口
原文链接:http://www.cnblogs.com/xdp-gacl/p/3651121.html 一.接口的概念 JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如"金丝猴是 ...
- Java基础05 实施接口
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在封装与接口中,private关键字封装了对象的内部成员.经过封装,产品隐藏了内部 ...
- Java命名和目录接口——JNDI
JNDI即Java命名和目录接口(JavaNaming and Directory Interface),它属于J2EE规范范畴,是J2EE的核心技术之一,提供了一组接口.类和关于命名空间的概念.JD ...
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
随机推荐
- 使用Python实现深度学习模型:序列到序列模型(Seq2Seq)
本文分享自华为云社区<使用Python实现深度学习模型:序列到序列模型(Seq2Seq)>,作者: Echo_Wish. 序列到序列(Seq2Seq)模型是一种深度学习模型,广泛应用于机器 ...
- 采用Dapr 的IoT 案例
CNCF 发布了一篇Dapr 的IoT 案例:Tempestive uses Dapr and K8s to track IoT messages | CNCF.Tempestive 是一家物联网解决 ...
- SELinux策略语法以及示例策略
首发公号:Rand_cs SELinux策略语法以及示例策略 本文来讲述 SELinux 策略常用的语法,然后解读一下 SELinux 这个项目中给出的示例策略 安全上下文 首先来看一下安全上下文的格 ...
- kettle从入门到精通 第四十一课 kettle 事务(单个转换文件)
1.大家都知道,我们在平常写java或者C#等代码时,如果涉及操作多个表时为了保持数据一致性需要开启事务,同样kettle也支持事务,今天我们一起来学习下kettle 单个转换文件内的事务特性. 转换 ...
- java springboot 指定运行端口
java springboot 指定运行端口 方法1: 修改源代码里的"\src\main\resources\application.properties" 文件,增加或修改 s ...
- 白话理解和使用DOCKER VOLUME
Docker使用Volume来管理宿主机和容器内数据的映射 什么是数据卷(Volume)Docker镜像被存储在一系列的只读层中.当我们创建一个容器时,Docker会读取镜像(只读),并在其顶部添加 ...
- Javascript高级程序设计第三章 | ch3 | 阅读笔记
语言基础 语法 标识符 注释 // /* */ 严格模式 // 也可以单独指定在一个函数中进行 'use strict' 语句 语句末尾分号不是必须的,但是最好加上 加上分号方便开发者删除空行压缩代码 ...
- CUDA程序优化-1.基础介绍
简介 本合集主要介绍我在开发分布式异构训练框架时的CUDA编程实践和性能优化的相关内容.主要包含以下几个部分: 介绍CUDA的基本概念和架构,帮助读者建立对CUDA的初步认识,包括硬件架构/CUDA基 ...
- uniapp 使用z-paging 分页组件 写在头部插槽内的单选按钮无法点击
这个问题是因为组件层级太低 <z-paging ref="paging" v-model="dataList" @query="queryLis ...
- TensorFLow手写字识别深度学习网络分析详解
Tensorflow和MNIST简介 TensorFlow 是一个采用数据流图,用于数值计算的开源软件库.它是一个不严格的"神经网络"库,可以利用它提供的模块搭建大多数类型的神经网 ...