springmvc项目中使用@CachePut缓存数据到redis的问题

发布于 2022-09-05 19:27:52 字数 5218 浏览 12 评论 0

在springmvc项目中使用@CachePut缓存数据到redis,存储到redis的数据变成了key和value独立的两条数据:
springmvc项目缓存结果
而在springboot项目中进行相同的操作却没用这样的问题,缓存的是正常的数据:
springboot项目缓存结果
springmvc项目中redis的相关如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置JedisPoolConfig相关参数 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${spring.redis.pool.maxTotal}"></property>
        <property name="maxIdle" value="${spring.redis.pool.maxIdle}"></property>
        <property name="minIdle" value="${spring.redis.pool.minIdle}"></property>
        <property name="maxWaitMillis" value="${spring.redis.pool.maxWait}"></property>
    </bean>

    <!-- 配置redis服务器信息 -->
    <bean id="connectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="poolConfig" ref="poolConfig"></property>
        <property name="hostName" value="${spring.redis.host}"></property>
        <property name="port" value="${spring.redis.port}"></property>
        <property name="password" value="${spring.redis.password}"></property>
        <property name="database" value="${spring.redis.database}"></property>
        <property name="timeout" value="${spring.redis.timeout}"></property>
    </bean>

    <!-- 配置RedisCacheManager -->
    <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
    </bean>

    <!-- 配置redis连接池 -->
    <bean class="redis.clients.jedis.JedisPool">
        <constructor-arg ref="poolConfig"/>
        <constructor-arg value="${spring.redis.host}"/>
        <constructor-arg type="int" value="${spring.redis.port}"/>
        <constructor-arg type="int" value="${spring.redis.timeout}"/>
        <constructor-arg type="java.lang.String" value="${spring.redis.password}"/>
        <constructor-arg type="int" value="${spring.redis.database}"/>
    </bean>

</beans>

以及

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    private static final Java8TimePatternProperties properties = new Java8TimePatternProperties();

    @Bean
    public RedisTemplate<String , Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(properties.dateFormatter()));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(properties.timeFormatter()));
        javaTimeModule.addSerializer(YearMonth.class, new YearMonthSerializer(properties.yearMonthFormatter()));
        javaTimeModule.addSerializer(MonthDay.class, new MonthDaySerializer(properties.monthDayFormatter()));
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(properties.dateTimeFormatter()));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(properties.dateFormatter()));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(properties.timeFormatter()));
        javaTimeModule.addDeserializer(YearMonth.class, new YearMonthDeserializer(properties.yearMonthFormatter()));
        javaTimeModule.addDeserializer(MonthDay.class, new MonthDayDeserializer(properties.monthDayFormatter()));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(properties.dateTimeFormatter()));
        mapper.registerModule(javaTimeModule);
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }

}

请问是哪里配置有问题吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

表情可笑 2022-09-12 19:27:52

找到原因了,RedisCacheManager里的usePrefix默认为false,

clipboard.png
跟踪源码发现usePrefix=false时,key也会存为一行数据:
clipboard.png

clipboard.png

解决办法

去掉xml配置里的RedisCacheManager配置,

   <!-- 配置RedisCacheManager -->
   <!-- <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg name="redisOperations" ref="redisTemplate" />
    </bean> -->

在JavaConfig里面加上如下配置:

    @Bean
    public RedisCacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }

RedisCacheManagerusePrefix改为true即可。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文