You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot RedisTemplate存Token报错NoSuchMethodError,求解决

解决Redis存储Token时的NoSuchMethodError异常

问题场景

计划在Redis中存储Token,编写了如下配置类和业务代码:

RedisConfig配置类

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName("127.0.0.1");
        redisStandaloneConfiguration.setPort(6379);

        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
        return jedisConnectionFactory;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

Service业务代码

final var st =AuthenticationSuccessDto
                .builder()
                .accessToken(jwtUtils.generateAccessToken(user))
                .refreshToken(jwtUtils.generateRefreshToken(user))
                .tokenType("Bearer")
                .user(user)
                .expiresIn(TimeUnit.SECONDS.toSeconds(60)).build();

try {
    redisTemplate.opsForHash().put(KEY,"1",st.getAccessToken());
} catch (Exception e) {
    e.printStackTrace();
    throw new Exception();
}

return st;

运行时抛出异常:

java.lang.NoSuchMethodError: 'long redis.clients.jedis.Jedis.hset(byte[], byte[], byte[])'

问题原因

  1. RedisTemplate序列化配置冲突:配置中重复设置HashKeySerializer,先指定为StringRedisSerializer后又覆盖为JdkSerializationRedisSerializer,且泛型为<String,String>的RedisTemplate使用JDK序列化会导致逻辑混乱。
  2. 依赖版本不兼容:Spring Data Redis与Jedis版本不匹配,导致调用的hset方法签名(返回值、参数)在当前Jedis版本中不存在。
  3. 该异常不需要手动将字符串转为字节,RedisTemplate的序列化器会自动处理类型转换。

解决方案

1. 修复RedisTemplate序列化配置

因存储的是字符串类型Token,统一使用StringRedisSerializer适配泛型,避免序列化冲突:

@Bean
public RedisTemplate<String, String> redisTemplate() {
    RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(jedisConnectionFactory());
    StringRedisSerializer stringSerializer = new StringRedisSerializer();
    // 统一配置序列化器
    redisTemplate.setKeySerializer(stringSerializer);
    redisTemplate.setValueSerializer(stringSerializer);
    redisTemplate.setHashKeySerializer(stringSerializer);
    redisTemplate.setHashValueSerializer(stringSerializer);
    redisTemplate.setEnableTransactionSupport(true);
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

2. 对齐Spring Data Redis与Jedis版本

确保两者版本兼容,若使用Spring Boot,建议通过依赖管理统一版本:

  • Maven示例:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <!-- Spring Boot自动匹配兼容版本,无需手动指定 -->
</dependency>

手动管理版本时,参考Spring官方文档的版本兼容矩阵,保证Jedis版本与Spring Data Redis版本匹配。

3. 优化业务代码(可选)

  • 给Token设置过期时间,避免Redis存储无效数据:
try {
    String hashKey = "1";
    redisTemplate.opsForHash().put(KEY, hashKey, st.getAccessToken());
    // 给整个KEY设置过期时间,与Token有效期保持一致
    redisTemplate.expire(KEY, st.getExpiresIn(), TimeUnit.SECONDS);
} catch (Exception e) {
    e.printStackTrace();
    throw new RuntimeException("存储Token到Redis失败", e);
}
  • 避免直接抛出Exception,改用更具体的自定义异常或RuntimeException,便于上层逻辑处理。

内容的提问来源于stack exchange,提问作者Borka192

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:15:35