Spring boot caching with redis,key have \xac\xed\x00\x05t\x00\x06

14,326

Solution 1

The caching - feature of Spring allows to use different cache - implementations. One of them is Redis. It can be used with the class RedisCacheManager. The Spring documentation says:

If Redis is available and configured, the RedisCacheManager is auto-configured.

This is the approach that I propose to influence the Redis - caching - integration:

  1. Define the RedisCacheManager as bean on your own.

  2. Pass the RedisTemplate to the constructor of RedisCacheManager.

I found an example for this on the Internet using a programmmatic configuration. There is also an example using XML-based configuration.

Solution 2

Create a redis template

private RedisTemplate<String, ?> createRedisTemplateForEntity() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(getRedisConnectionFactory());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();

    return redisTemplate;
}

Why is it creating a weird string as key?

The key is created based on the argument attributes present in your method which is annotated as cacheable. This is how spring reads the cache value from redis.

Solution 3

like mm759's answer:

  1. Define the RedisCacheManager as bean on your own.

    1. Pass the RedisTemplate to the constructor of RedisCacheManager.

this code will solve my problem:

package io;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Created by freezhan on 16/9/5.
 */
@Configuration
public class CacheConfig {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Bean
    public CacheManager cacheManager() {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
    }

}

and the redis store like this:

enter image description here

Share:
14,326

Related videos on Youtube

free斩
Author by

free斩

Updated on September 16, 2022

Comments

  • free斩
    free斩 3 months

    I want to use Spring cache @Cacheable to manager cache. And the real cache is redis.

    my code like that:

    @PostMapping("/post")
    @CachePut(value = "abc", key = "#key")
    public String putInRedis(@RequestParam String key, @RequestParam String value) {
        saveInDB(key, value);
    
        return value;
    }
    
    @GetMapping("/get")
    @Cacheable(value = "abc", key = "#key")
    public String queryRedis(@RequestParam String key) {
    
        return findByKey(key);
    }
    

    After I have the post request which is

    localhost:8080/post?key=key&value=value

    the redis server appear a weird key

    127.0.0.1:6379> keys *
    1) "abc:\xac\xed\x00\x05t\x00\x03key"
    127.0.0.1:6379> GET "abc:\xac\xed\x00\x05t\x00\x03key"
    "\xac\xed\x00\x05t\x00\x05value"
    

    Spring caching

    weird-redis-key-with-spring-data-jedis

    how to set @Cacheable's Serializer like StringRedisTemplate default:

    public StringRedisTemplate() {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        setKeySerializer(stringSerializer);
        setValueSerializer(stringSerializer);
        setHashKeySerializer(stringSerializer);
        setHashValueSerializer(stringSerializer);
    }
    

    my application.properties:

    spring.redis.host=localhost
    spring.redis.password=
    spring.redis.port=6379
    

    build.gradle

    group 'io.freezhan'
    version '1.0-SNAPSHOT'
    
    buildscript {
        repositories {
            maven {
                url 'https://plugins.gradle.org/m2/'
            }
        }
        dependencies {
            classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE'
        }
    }
    
    task wrapper(type: Wrapper) {
        gradleVersion = '2.13'
        distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
    }
    
    apply plugin: 'java'
    apply plugin: 'spring-boot'
    
    sourceCompatibility = 1.5
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web") {
            exclude module: "spring-boot-starter-tomcat"
        }
        compile("org.springframework.boot:spring-boot-starter-data-redis")
        compile("org.springframework.boot:spring-boot-starter-jetty")
        compile("org.springframework.boot:spring-boot-starter-actuator")
        compile 'org.projectlombok:lombok:1.16.10'
        testCompile("junit:junit")
    }
    
    • free斩
      free斩 over 6 years
      my application.properties is spring.redis.host=localhost spring.redis.password= spring.redis.port=6379
  • free斩
    free斩 over 6 years
    The default RedisTemplate will not appear weird key, because the serializer is StringRedisSerializer. But the default @Cacheable(value = "abc", key = "#key") maybe use defaultSerializer = new JdkSerializationRedisSerializer(); Define own cacheManager and set this redisTemplate will solve my problem. thanks for your answer
  • free斩
    free斩 over 6 years
    Is there any way implement this in application.properties or yaml file. Don't use to write code~
  • mm759
    mm759 over 6 years
    I hardly know both, but I think it's not possible. I couldn't find annotations on RedisCacheManager that allow it.
  • aswzen
    aswzen almost 4 years
    its deprecated..now RedisCacheManager not allowing StringRedisTemplate to be in parameter
  • echoaman
    echoaman over 1 year
    Passing RedisTemplate to the constructor of RedisCacheManager is deprecated now. Any new way to stop the weird key generation?