生成图形验证码

4.3.1.1 导入工具类

(1) 导入Constants 常量类
/*** 通用常量类* @author spikeCong* @date 2023/5/3**/
public class Constants {/*** UTF-8 字符集*/public static final String UTF8 = "UTF-8";/*** GBK 字符集*/public static final String GBK = "GBK";/*** http请求*/public static final String HTTP = "http://";/*** https请求*/public static final String HTTPS = "https://";/*** 通用成功标识*/public static final String SUCCESS = "0";/*** 通用失败标识*/public static final String FAIL = "1";/*** 登录成功*/public static final String LOGIN_SUCCESS = "Success";/*** 注销*/public static final String LOGOUT = "Logout";/*** 登录失败*/public static final String LOGIN_FAIL = "Error";/*** 验证码 redis key*/public static final String CAPTCHA_CODE_KEY = "captcha_codes:";/*** 登录用户 redis key*/public static final String LOGIN_TOKEN_KEY = "login_tokens:";/*** 防重提交 redis key*/public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";/*** 验证码有效期(分钟)*/public static final Integer CAPTCHA_EXPIRATION = 2;/*** 令牌*/public static final String TOKEN = "token";/*** 令牌前缀*/public static final String TOKEN_PREFIX = "Bearer ";/*** 令牌前缀*/public static final String LOGIN_USER_KEY = "login_user_key";/*** 用户ID*/public static final String JWT_USERID = "userid";/*** 用户名称*/public static final String JWT_USERNAME = "sub";/*** 用户头像*/public static final String JWT_AVATAR = "avatar";/*** 创建时间*/public static final String JWT_CREATED = "created";/*** 用户权限*/public static final String JWT_AUTHORITIES = "authorities";/*** 参数管理 cache key*/public static final String SYS_CONFIG_KEY = "sys_config:";/*** 字典管理 cache key*/public static final String SYS_DICT_KEY = "sys_dict:";/*** 资源映射路径 前缀*/public static final String RESOURCE_PREFIX = "/profile";/*** 默认为空消息*/public static final String DEFAULT_NULL_MESSAGE = "暂无承载数据";/*** 默认成功消息*/public static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";/*** 默认失败消息*/public static final String DEFAULT_FAILURE_MESSAGE = "操作失败";
}
(2) 导入UUIDUtils

UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。

/*** UUID生成器工具类* @author spikeCong* @date 2023/5/3**/
public class UUIDUtils {/*** 获取随机UUID** @return 随机UUID*/public static String randomUUID(){return UUID.randomUUID().toString();}/*** 简化的UUID,去掉了横线** @return 简化的UUID,去掉了横线*/public static String simpleUUID(){return UUID.randomUUID().toString().replaceAll("-", "");}
}
(3) 导入Kv类 链式map

链式映射是指在 Java 中使用 Map 接口的一种实现方式,它允许在一个键值映射中进行多次操作而无需创建新的 Map 对象。例如,可以在同一个 Map 中链式地添加、删除或更新键值对。

核心就是 重写 Map 接口的 put() 方法,以返回 this 引用,以实现链式调用

/*** 链式Map*  继承 LinkedCaseInsensitiveMap, 对key大小写不敏感的LinkedHashMap实现* @author spikeCong* @date 2023/5/3**/
public class ChainedMap extends LinkedCaseInsensitiveMap<Object> {private ChainedMap() {super();}/*** 创建ChainedMap** @return ChainedMap*/public static ChainedMap create() {return new ChainedMap();}public static <K, V> HashMap<K, V> newMap() {return new HashMap<>(16);}/*** 设置列** @param attr  属性* @param value 值* @return 本身*/public ChainedMap set(String attr, Object value) {this.put(attr, value);return this;}/*** 设置全部** @param map 属性* @return 本身*/public ChainedMap setAll(Map<? extends String, ?> map) {if (map != null) {this.putAll(map);}return this;}/*** 设置列,当键或值为null时忽略** @param attr  属性* @param value 值* @return 本身*/public ChainedMap setIgnoreNull(String attr, Object value) {if (attr != null && value != null) {set(attr, value);}return this;}public Object getObj(String key) {return super.get(key);}/*** 获得特定类型值** @param <T>          值类型* @param attr         字段名* @param defaultValue 默认值* @return 字段值*/@SuppressWarnings("unchecked")public <T> T get(String attr, T defaultValue) {final Object result = get(attr);return (T) (result != null ? result : defaultValue);}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public String getStr(String attr) {if (null == attr || attr.equals(StringPool.NULL)) {return StringPool.NULL;}return attr;}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Integer getInt(String attr) {if (attr == null) {return -1;}try {return Integer.valueOf(attr);} catch (final NumberFormatException nfe) {return -1;}}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Long getLong(String attr) {if (attr == null) {return -1L;}try {return Long.valueOf(attr);} catch (final NumberFormatException nfe) {return -1L;}}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Float getFloat(String attr) {if (attr != null) {return Float.valueOf(attr.trim());}return null;}public Double getDouble(String attr) {if (attr != null) {return Double.valueOf(attr.trim());}return null;}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Boolean getBool(String attr) {if (attr != null) {String val = String.valueOf(attr);val = val.toLowerCase().trim();return Boolean.parseBoolean(val);}return null;}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public byte[] getBytes(String attr) {return get(attr, null);}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Date getDate(String attr) {return get(attr, null);}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Time getTime(String attr) {return get(attr, null);}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Timestamp getTimestamp(String attr) {return get(attr, null);}/*** 获得特定类型值** @param attr 字段名* @return 字段值*/public Number getNumber(String attr) {return get(attr, null);}@Overridepublic ChainedMap clone() {ChainedMap clone = new ChainedMap();clone.putAll(this);return clone;}
}
(4) 导入序列化工具类

添加序列化工具类,让Redis使用FastJson序列化,提高序列化效率, 将存储在Redis中的value值,序列化为JSON格式便于查看

public class FastJsonJsonRedisSerializer<T> implements RedisSerializer<T>
(5) 导入Redis工具类
  • 当Redis当做数据库或者消息队列来操作时,我们一般使用RedisTemplate来操作
  • 当Redis作为缓存使用时,我们可以将它作为Spring Cache的实现,直接通过注解使用
@Component
public class RedisCache{}
(6) 导入redis配置类
@Configuration
public class RedisConfig {}

4.3.1.2 生成验证码

(1) 导入依赖
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency>
(2) application.yml 增加redis配置
# Spring配置
spring:# redis 配置redis:# 地址host: localhost# 端口,默认为6379port: 6379# 密码password:# 连接超时时间timeout: 10sjedis:pool:# 连接池中的最小空闲连接min-idle: 3# 连接池中的最大空闲连接max-idle: 8# 连接池的最大数据库连接数max-active: 8# #连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms
(3) 创建CaptchaController
@RestController
public class CaptchaController {//当Redis当做数据库或者消息队列来操作时,我们一般使用RedisTemplate来操作@Autowiredprivate RedisTemplate redisTemplate;/*** 生成验证码* @param response* @return: com.mashibing.springsecurity_example.common.ResponseResult*/@GetMapping("/captchaImage")public ChainedMap getCode(HttpServletResponse response){SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);//生成验证码,及验证码唯一标识String uuid = UUIDUtils.simpleUUID();String key = Constants.CAPTCHA_CODE_KEY + uuid;String code = specCaptcha.text().toLowerCase();//保存到redisredisTemplate.opsForValue().set(key, code, Duration.ofMinutes(30));return ChainedMap.create().set("uuid",uuid).set("img",specCaptcha.toBase64());}
}
(4) 查看接口文档进行测试

4.3.2 登录接口实现

4.3.2.1 数据库查询用户信息

(1) 创建SysUser类
  • 创建sys_user表对应实体类, com.msb.hjycommunity.system.domain.SysUser
public class SysUser extends BaseEntity {/** 用户ID */@Excel(name = "用户序号")@TableIdprivate Long userId;/** 部门ID */@Excel(name = "部门编号")private Long deptId;/** 用户账号 */@Excel(name = "登录名称")private String userName;/** 用户昵称 */@Excel(name = "用户名称")private String nickName;/** 用户邮箱 */@Excel(name = "用户邮箱")private String email;/** 手机号码 */@Excel(name = "手机号码")private String phonenumber;/** 用户性别 */@Excel(name="用户性别",replace = {"男_0","女_1","未知_0"})private String sex;/** 用户头像 */private String avatar;/** 密码 */private String password;/** 盐加密 */private String salt;/** 帐号状态(0正常 1停用) */@Excel(name = "帐号状态",replace = {"正常_0","停用_1"})private String status;/** 删除标志(0代表存在 2代表删除) */private String delFlag;/** 最后登录IP */@Excel(name = "最后登录IP")private String loginIp;/** 最后登录时间 */@Excel(name = "最后登录时间", width = 30, format = "yyyy-MM-dd HH:mm:ss")private Date loginDate;public SysUser() {}//对 用户名 邮箱 手机号进行校验@NotBlank(message = "用户账号不能为空")@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")    public String getUserName() {return userName;}@Email(message = "邮箱格式不正确")@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")public String getEmail() {return email;}@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")public String getPhonenumber() {return phonenumber;}//序列化时忽略密码@JsonIgnorepublic String getPassword() {return password;}//......
}
(2) 创建 SysUserMapper
public interface SysUserMapper extends BaseMapper<SysUser> {/*** 通过用户名查询用户* @param userName 用户名* @return 用户对象信息*/public SysUser selectUserByUserName(String userName);
}
<mapper namespace="com.msb.hjycommunity.system.mapper.SysUserMapper"><select id="selectUserByUserName" parameterType="string" resultType="SysUser">SELECT * FROM sys_user where user_name = #{userName}</select></mapper>
  • 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestHjyCommunityApplication {@AutowiredSysUserMapper userMapper;@Testpublic void testSelectUserByUserName(){SysUser admin = userMapper.selectUserByUserName("admin");System.out.println(admin);}
}
(3) 创建 SysUserService
public interface SysUserService {/*** 通过用户名查询用户* @param userName * @return: com.msb.hjycommunity.system.domain.SysUser*/public SysUser selectUserByUserName(String userName);
}
@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {@Resourceprivate SysUserMapper sysUserMapper;@Overridepublic SysUser selectUserByUserName(String userName) {return sysUserMapper.selectUserByUserName(userName);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端魔法进阶:Vue 3源码解析与新特性对比!

一、引言 Vue 3作为前端开发的魔法杖&#xff0c;为我们带来了更快、更小、更强大的全新体验。它的源码是前端领域的宝藏&#xff0c;隐藏着无数神秘的魔法。在本篇博客中&#xff0c;我将带你踏上一段探索Vue 3源码之旅&#xff0c;解析这个前端魔法的奥秘&#xff0c;让你深…

负载均衡的策略有哪些? 负载均衡的三种方式?

负载均衡的策略有哪些? 负载均衡的策略有如下&#xff1a; 1. 轮询&#xff08;Round Robin&#xff09;&#xff1a;按照请求的顺序轮流分配到不同的服务器。 2. 权重&#xff08;Weighted&#xff09;&#xff1a;给不同的服务器分配不同的权重&#xff0c;根据权重比例来…

抽象工厂模式——产品族的创建

1、简介 1.1、简介 抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比&#xff0c;抽象工厂模式中的具体工厂不只是创建一种产品&#xff0c;它负责创建一族产品 1.2、定义 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;&#xff1a;提供…

【vim 学习系列文章 2 - vim 常用插件配置】

文章目录 1.1 vim 常用插件1.1.1 vim 插件 Pathogen 管理1.1.2 vim 常用插件推荐1.1.3 vim Leaderf1.1.4 vim ripgrep 工具1.1.5 vim Leaderf 配合 rg1.1.6 vim autocmd 配置 1.2 其它类型文件 vimrc 配置1.2.1 System Verilog vimrc 配置 上篇文章&#xff1a;vim 学习系列文章…

Acwing.898 数字三角形(动态规划)

题目 给定一个如下图所示的数字三角形&#xff0c;从顶部出发&#xff0c;在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点&#xff0c;一直走到底层&#xff0c;要求找出─条路径&#xff0c;使路径上的数字的和最大。 输入格式 第一行包含整数n&#xff0…

螺旋矩阵 II

给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]] 示例 2&#xff1a; 输入&#xff1a;n 1 输出&a…

VBA操作WORD(八)设置标题格式(含主、副标题)

因为主标题和副标题一般都是包含一两句子的段落&#xff0c;所以参数直接传入Paragraph。至于判断主副标题的规则则外面调用部分再做判断。 Sub 设置主标题格式(ib As Paragraph)With ActiveDocument.Paragraphs(1).Range.Style ActiveDocument.Styles(wdStyleHeading1)设置为…

零信任网络架构与实现技术的研究与思考

目前&#xff0c;国外已有较多有关零信任网络的研究与实践&#xff0c;包括谷歌的 BeyondCorp、BeyondProd&#xff0c;软件定义边界&#xff08;Software Defined Perimeter&#xff0c;SDP&#xff09; 及盖特提出的“持续自适应风险与信任评估”等。国内也有不少安全厂商积极…

uView 在 uni-app 中的使用

文章目录 一、uView是什么&#xff1f;1.uView 安装2.uView 在 uni-app 中的使用 一、uView是什么&#xff1f; 提示&#xff1a;正文内容&#xff1a; uView 官网&#xff1a; https://www.uviewui.com uView 是 uni-app 生态专用的 UI 框架 关于uView的取名来由&#xff0c…

vue中预览静态pdf文件

方法 // pdf预览 viewFileCompare() { const pdfUrl "/static/wjbd.pdf"; window.open(pdfUrl); }, // 下载 downloadFile(){ var a document.createElement("a"); a.href "/static/wjbd.pdf"; a.…

学生管理系统-03项目案例(3)

一、用户列表 1、编写api接口 //导入封装后的axios import {instance} from /util/request export default{getUsers:params>instance.get(/users/getUsers,{params}) } 2、表格渲染 <template><el-card><!-- 当el-table元素中注入data对象数组后&#x…

React之组件间通信

React之组件间通信 组件通信&#xff1a; 简单讲就是组件之间的传值&#xff0c;包括state、函数等 1、父子组件通信 父组件给子组件传值 核心&#xff1a;1、自定义属性&#xff1b;2、props 父组件中: 自定义属性传值 import Header from /components/Headerconst Home ()…

关于Anaconda环境配置的一些问题

文章目录 一、关于package文件安装位置二、关于尝试下载Python包时出现的CondaSSLError三、配置环境的整个流程 一、关于package文件安装位置 package 文件安装在envs目录底下的Lib中&#xff0c;可以参考一下。 在对应的Python脚本文件中&#xff0c;选择Parameters&#xff0…

【Spring】Spring 总览

一、简单介绍一下 Spring Spring是一个全面的、企业应用开发的一站式解决方案&#xff0c;贯穿表现层、业务层、持久层&#xff0c;可以轻松和其他框架整合&#xff0c;具有轻量级、控制反转、面向切面、容器等特征。 轻量级 &#xff1a; 空间开销和时间开销都很轻量 控制反…

蓝桥杯单片机第十二届国赛 真题+代码

iic.c /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础&#xff0c;根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求&#xff0c;进行代码调试和修改。 */ #include <STC1…

antd vue tree的增删改和拖拽

最近项目中遇到一个tree型数据的的操作的功能&#xff0c;代码简单如下&#xff1a; <a-treeshowLineshowIcon:draggable"draggable":expandedKeys"expandedKeys":treeData"treeData"drop"onDrag"expand"onExpand">&l…

java springBoot 整合日志

1.在Spring Boot项目的resources目录下创建一个新的logback.xml文件。 2.logback.xml中&#xff0c;配置 代码 <?xml version"1.0" encoding"UTF-8"?> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL…

了解Unity编辑器之组件篇Physics 2D(十二)

一、Area Effector 2D区域施加力&#xff09;&#xff1a;用于控制区域施加力的行为 Use Collider Mask&#xff08;使用碰撞器遮罩&#xff09;&#xff1a;启用后&#xff0c;区域施加力仅会作用于特定的碰撞器。可以使用Collider Mask属性选择要作用的碰撞器。 Collider Ma…

vmware中windows操作系统虚拟机安装

1.win10中安装 1.1 虚拟机向导 文件-新建虚拟机 典型-下一步 稍后安装操作系统-下一步 window10 64x -下一步 修改虚拟机名称及位置-下一步 默认60g,至少大于40g-将虚拟磁盘拆分成多个文件夹-下一步 点击完成 1.2 编辑虚拟机设置 移除打印机 设置虚拟机&#xff0c;加入iso映…

【隐式动态求解】使用非线性纽马克方法的隐式动态求解研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…