新闻中心
Spring Boot集成RedisTemplate进行数据存储教程

本教程旨在指导如何在Spring Boot应用中有效集成和使用RedisTemplate,实现数据(如用户令牌)的存储。文章将涵盖Spring Boot的自动配置机制、手动配置Redis连接工厂与RedisTemplate的细节,重点讲解不同序列化器的选择及其对数据存储的影响,并提供避免常见错误(如NoSuchMethodError)的实践建议。
Spring Boot集成RedisTemplate进行数据存储
在Spring Boot应用中利用Redis进行数据缓存或存储是常见的需求,尤其是在处理用户会话或令牌等场景。Spring Data Redis提供了强大的抽象,其中RedisTemplate是与Redis进行交互的核心组件。本文将详细介绍如何在Spring Boot项目中配置和使用RedisTemplate,并解决可能遇到的常见问题。
1. 快速配置:利用Spring Boot自动配置
Spring Boot为Redis提供了便捷的自动配置功能,这是推荐的集成方式。通过简单的配置,Spring Boot会自动创建JedisConnectionFactory或LettuceConnectionFactory(取决于你引入的依赖)以及一个默认的RedisTemplate实例。
你只需在application.yml或application.properties文件中添加Redis连接信息:
spring:
redis:
host: localhost
port: 6379
# password: your_redis_password # 如果Redis有密码
# database: 0 # 选择Redis数据库,默认为0完成上述配置后,Spring Boot会自动配置好Redis连接,你就可以直接在Service层或Repository层注入RedisTemplate或StringRedisTemplate进行使用了。
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class TokenService {
private final RedisTemplate<String, Object> redisTemplate;
// 推荐使用构造器注入
public TokenService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void storeToken(String userId, String token) {
// 使用opsForValue()存储简单的键值对
redisTemplate.opsForValue().set("user:token:" + userId, token);
}
public String getToken(String userId) {
// 获取令牌
return (String) redisTemplate.opsForValue().get("user:token:" + userId);
}
}注意事项:
- 默认情况下,Spring Boot的RedisTemplate会使用JdkSerializationRedisSerializer进行值的序列化。这意味着存储到Redis的数据是J*a对象序列化后的二进制形式。
- 如果需要存储纯字符串或JSON数据,推荐使用StringRedisTemplate,它默认使用StringRedisSerializer,或者对RedisTemplate进行定制。
2. 手动配置RedisTemplate与序列化器
在某些特定场景下,例如需要更细粒度的控制、使用不同的连接池配置、或者自定义序列化策略时,你可能需要手动配置RedisConnectionFactory和RedisTemplate。
以下是一个手动配置RedisTemplate的示例,旨在解决常见的序列化问题并优化配置:
若冰企业商务平台.net
集企业自助建站、网络营销、商品推广于一体的系统 功能说明: 1、系统采用Microsoft SQL Server大型数据库支持,查询数据库用的全是存储过程,速度和性能极好。开发环境是vs.net,采用4层结构,具有很好的可维护性和可扩冲性。 2、用户注册和登陆 未注册用户只具备浏览商品、新闻和留言功能;要采购商品,需接受服务协议并填写相关注册信息成为正式用户后方可进行,以尽可能减少和避免无效
0
查看详情
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
/**
* 配置Jedis连接工厂。
* 推荐使用LettuceConnectionFactory作为更现代的选择,但此处沿用JedisConnectionFactory以匹配原始问题背景。
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName("localhost"); // 确保与application.yml一致或直接硬编码
redisStandaloneConfiguration.setPort(6379);
// redisStandaloneConfiguration.setPassword(RedisPassword.of("your_password")); // 如果有密码
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
/**
* 配置RedisTemplate,指定键和值的序列化方式。
* 对于存储字符串或JSON对象,推荐使用StringRedisSerializer和GenericJackson2JsonRedisSerializer。
*/
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
// 使用StringRedisSerializer来序列化和反序列化Redis的key值
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer); // Hash的key也使用String序列化
// 使用GenericJackson2JsonRedisSerializer来序列化和反序列化Redis的value值(默认使用JDK序列化)
// 这使得存储的对象以JSON字符串形式存储,易于阅读和跨语言互操作
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer); // Hash的value也使用JSON序列化
template.setEnableTransactionSupport(false); // 根据需要开启或关闭事务支持
template.afterPropertiesSet();
return template;
}
}在上述配置中,我们做了以下改进:
- 连接工厂:jedisConnectionFactory()方法负责创建与Redis服务器的连接。
-
序列化器选择:
- setKeySerializer(new StringRedisSerializer()):将所有Redis键(包括主键和Hash键)序列化为UTF-8字符串。
- setValueSerializer(new GenericJackson2JsonRedisSerializer()):将所有Redis值(包括Hash值)序列化为JSON字符串。GenericJackson2JsonRedisSerializer比JdkSerializationRedisSerializer更通用,它将J*a对象转换为人类可读的JSON格式,便于调试和跨语言互操作。如果你的值只是简单字符串,也可以直接使用StringRedisSerializer。
- 避免重复配置:原始代码中setHashKeySerializer被调用了两次,后一次会覆盖前一次。这里我们明确指定了Hash键和值的序列化器。
3. 使用RedisTemplate进行数据操作
一旦RedisTemplate配置完成,你就可以在业务逻辑中注入并使用它来执行各种Redis操作。
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import j*a.util.concurrent.TimeUnit;
@Service
public class AuthenticationService {
private final RedisTemplate<String, Object> redisTemplate;
public AuthenticationService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
// 假设AuthenticationSuccessDto是一个包含accessToken等信息的DTO
public static class AuthenticationSuccessDto {
private String accessToken;
private String refreshToken;
private String tokenType;
private Object user; // 示例,可以是User对象或其他
private Long expiresIn;
// 省略构造器、getter、setter、builder等
public String getAccessToken() { return accessToken; }
public String getRefreshToken() { return refreshToken; }
public String getTokenType() { return tokenType; }
public Object getUser() { return user; }
public Long getExpiresIn() { return expiresIn; }
public AuthenticationSuccessDto setAccessToken(String accessToken) { this.accessToken = accessToken; return this; }
public AuthenticationSuccessDto setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; return this; }
public AuthenticationSuccessDto setTokenType(String tokenType) { this.tokenType = tokenType; return this; }
public AuthenticationSuccessDto setUser(Object user) { this.user = user; return this; }
public AuthenticationSuccessDto setExpiresIn(Long expiresIn) { this.expiresIn = expiresIn; return this; }
}
private static final String USER_TOKENS_KEY_PREFIX = "user:tokens:";
/**
* 存储用户认证信息,使用Redis的Hash结构。
*
* @param userId 用户ID
* @param authDto 认证成功DTO
*/
public AuthenticationSuccessDto storeAuthenticationInfo(String userId, AuthenticationSuccessDto authDto) {
String hashKey = USER_TOKENS_KEY_PREFIX + userId;
try {
// 使用opsForHash().putAll()存储整个DTO,或者opsForHash().put()存储单个字段
// 这里为了演示,我们存储accessToken到Hash中
redisTemplate.opsForHash().put(hashKey, "accessToken", authDto.getAccessToken());
redisTemplate.opsForHash().put(hashKey, "refreshToken", authDto.getRefreshToken());
redisTemplate.opsForHash().put(hashKey, "expiresIn", authDto.getExpiresIn());
// 设置整个Hash的过期时间
if (authDto.getExpiresIn() != null && authDto.getExpiresIn() > 0) {
redisTemplate.expire(hashKey, authDto.getExpiresIn(), TimeUnit.SECONDS);
}
} catch (Exception e) {
System.err.println("存储认证信息到Redis失败: " + e.getMessage());
e.printStackTrace();
// 根据业务需求抛出自定义异常
throw new RuntimeException("Failed to store authentication info in Redis.", e);
}
return authDto;
}
/**
* 从Redis获取用户的访问令牌。
*
* @param userId 用户ID
* @return 访问令牌,如果不存在则返回null
*/
public String getAccessToken(String userId) {
String hashKey = USER_TOKENS_KEY_PREFIX + userId;
return (String) redisTemplate.opsForHash().get(hashKey, "accessToken");
}
}在上述AuthenticationService示例中:
- 我们定义了一个USER_TOKENS_KEY_PREFIX来构建Hash的主键。
- storeAuthenticationInfo方法使用redisTemplate.opsForHash().put()将AuthenticationSuccessDto中的关键信息存储到Redis的Hash结构中。
- redisTemplate.expire()用于为整个Hash设置过期时间,确保令牌的生命周期。
- getAccessToken方法演示了如何从Hash中检索特定字段。
4. 解决j*a.lang.NoSuchMethodError问题
j*a.lang.NoSuchMethodError: 'long redis.clients.jedis.Jedis.hset(byte[], byte[], byte[])' 错误通常发生在以下情况:
- 版本不兼容:spring-data-redis库与底层Jedis客户端库的版本不兼容。Spring Data Redis会根据其内部实现调用Jedis客户端的特定方法。如果Jedis版本过旧或过新,不包含Spring Data Redis期望的方法签名,就会抛出此错误。
- 依赖冲突:项目中引入了多个版本的Jedis或相关的Redis客户端库,导致运行时加载了错误的版本。
解决方案:
-
优先使用Spring Boot管理依赖:让Spring Boot Starter POMs (spring-boot-starter-data-redis) 来管理spring-data-redis和Jedis/Lettuce的版本。Spring Boot会选择一个已知兼容的版本组合。
- 确保你的pom.xml中只引入了spring-boot-starter-data-redis,并且没有显式地引入Jedis或Lettuce的特定版本,除非你明确知道需要覆盖Spring Boot的默认版本。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 如果需要JSON序列化,添加Jackson依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>
- 确保你的pom.xml中只引入了spring-boot-starter-data-redis,并且没有显式地引入Jedis或Lettuce的特定版本,除非你明确知道需要覆盖Spring Boot的默认版本。
-
检查依赖树:使用M*en (mvn dependency:tree) 或 Gradle (gradle dependencies) 命令检查项目的实际依赖树,查找是否存在Jedis或Lettuce的冲突版本。如果发现冲突,可以通过
标签排除不正确的版本。 - 更新Spring Boot版本:如果你的Spring Boot版本较旧,尝试升级到最新稳定版本,这通常会带来最新的兼容依赖。
总结
在Spring Boot中集成RedisTemplate进行数据存储,最佳实践是首先利用Spring Boot的自动配置功能。当需要更高级的定制时,可以手动配置JedisConnectionFactory(或LettuceConnectionFactory)和RedisTemplate,并特别注意选择合适的序列化器。对于存储字符串或JSON对象,StringRedisSerializer和GenericJackson2JsonRedisSerializer是常用的选择。遇到NoSuchMethodError时,应重点检查spring-data-redis和底层Redis客户端库的版本兼容性及依赖冲突,通常通过Spring Boot Starter的依赖管理可以有效避免此类问题。通过以上步骤,你可以构建一个健壮且高效的Redis数据存储解决方案。
以上就是Spring Boot集成RedisTemplate进行数据存储教程的详细内容,更多请关注其它相关文章!
# java
# 怀柔区定制网站建设收费
# 铜陵网站建设工作内容
# 医疗网站该怎么优化
# 公司邮箱网站建设
# 辽宁视频营销推广平台
# 柳北营销推广
# 军刀seo快排系统
# 媒体网站推广法的优势
# 目录下
# 若冰
# 是一个
# 客户端
# 推荐使用
# 数据存储
# 文档
# 转换为
# word
# redis
# js
# json
# 编码
# app
# access
# ai
# 常见问题
# 优化配置
# 键值对
# red
# 序列化
# 令牌
# 揭阳推广营销平台电话
# 福州鼓楼seo优化服务
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明
J*a递归快速排序中静态变量的状态管理与陷阱
CSS图片焦点样式实现教程:理解与应用tabindex属性
mcjs网页版流畅运行 mcjs低配电脑畅玩入口
html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】
Python字典中优雅地迭代剩余元素的方法
php源码怎么看淘宝客系统_看php源码淘宝客系统技巧
邮政快递包裹最新位置 邮政快递实时追踪入口
如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式
LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比
Eclipse怎么运行工程_Eclipse工程运行配置说明
Python中高效访问嵌套字典与列表中的键值对
windows10怎么查看硬盘序列号_windows10硬盘id查询命令
Win10如何恢复误删的快捷方式_Win10重建常用软件快捷方式
ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口
CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略
GemBox Document HTML转PDF垂直文本渲染问题及解决方案
蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址
DLsite中文平台入口 DLsite官网内容在线查看
J*aScript DOM操作:高效清空列表元素的策略与实践
深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现
漫蛙官网正版漫画入口 漫蛙2官方网页登录地址
Win11截图该按哪些键 Win11截屏完整流程解析【教程】
微信网页版扫码登录入口 微信网页版二维码登录入口
Python中如何避免重复条件判断:利用数据结构实现动态逻辑
自定义Bag-of-Words实现:处理带负号的词汇权重
如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】
为什么我的微信朋友圈看不到别人的更新_微信朋友圈更新显示异常解决方法
TikTok网页版直接登录 TikTok网页端官方平台入口
苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
ArrayList与LinkedList核心操作的Big-O复杂度分析
2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析
Win10怎么制作U盘启动盘 Win10系统安装U盘制作教程【详解】
Go语言中的*string:深入理解字符串指针
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题
sublime怎么格式化代码_sublime代码美化与一键排版插件配置
126邮箱账号注册 电脑版登录入口
微博网页版主页入口 微博官方网站免登录访问
深入理解J*aScript中的B样条曲线与节点向量生成
漫蛙2漫画入口 漫蛙正版网页漫画直达网址
C++ typeid如何获取类型信息_C++ RTTI运行时类型识别用法
qq音乐在线播放入口_qq音乐电脑版登录链接
excel如何生成目录 excel一键生成工作表目录超链接
手机CPU怎么影响游戏体验_手机CPU对游戏性能的影响分析
Python实现多节点属性重叠度分析教程
PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误


2025-12-08
浏览次数:次
返回列表
String hashKey = USER_TOKENS_KEY_PREFIX + userId;
try {
// 使用opsForHash().putAll()存储整个DTO,或者opsForHash().put()存储单个字段
// 这里为了演示,我们存储accessToken到Hash中
redisTemplate.opsForHash().put(hashKey, "accessToken", authDto.getAccessToken());
redisTemplate.opsForHash().put(hashKey, "refreshToken", authDto.getRefreshToken());
redisTemplate.opsForHash().put(hashKey, "expiresIn", authDto.getExpiresIn());
// 设置整个Hash的过期时间
if (authDto.getExpiresIn() != null && authDto.getExpiresIn() > 0) {
redisTemplate.expire(hashKey, authDto.getExpiresIn(), TimeUnit.SECONDS);
}
} catch (Exception e) {
System.err.println("存储认证信息到Redis失败: " + e.getMessage());
e.printStackTrace();
// 根据业务需求抛出自定义异常
throw new RuntimeException("Failed to store authentication info in Redis.", e);
}
return authDto;
}
/**
* 从Redis获取用户的访问令牌。
*
* @param userId 用户ID
* @return 访问令牌,如果不存在则返回null
*/
public String getAccessToken(String userId) {
String hashKey = USER_TOKENS_KEY_PREFIX + userId;
return (String) redisTemplate.opsForHash().get(hashKey, "accessToken");
}
}