首页 > 解决方案 > spring框架spring-data-redis序列化异常

问题描述

我对 Java 编程非常陌生。我是 C# 开发人员。我正在做一个小项目,我们想使用 redis 缓存而不是 ehcache。

我们使用的是 spring.data.redis 版本 2.2.3.RELEASE 和 redis.client.jedis 版本 3.2.0。

这是我的 redisconf 类,其中也包含 RedisTemplate:

public class RedisConf {
    private String REDIS_HOSTNAME = "localhost";
    private int REDIS_PORT = 6379;

    protected JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(REDIS_HOSTNAME, REDIS_PORT);
        JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder().usePooling().build();
        JedisConnectionFactory factory = new JedisConnectionFactory(configuration,jedisClientConfiguration);
        factory.afterPropertiesSet();
        return factory;
    }


    public RedisTemplate<String,Element> redisTemplate() {
        final RedisTemplate<String,Element> redisTemplate = new RedisTemplate<String,Element>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new GenericToStringSerializer<Object>(Object.class));
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

下面是实例化 RedisConf 类的方法:

RedisConf rf = new RedisConf();
RedisTemplate<String, Element> redisTemplate = rf.redisTemplate();
redisTemplate.getConnectionFactory().getConnection().ping();
cache = new RedisDelegate(redisTemplate);

这是我的 RedisDeligate 类,我在其中执行所有 get 和 put 操作:

public class RedisDelegate implements Cache {

    private final RedisTemplate<String,Element> redisTemplate;
    private final Logger LOGGER = LoggerFactory.getLogger(RedisDelegate.class);
    private static String REDIS_KEY = "Redis";

    public RedisDelegate(RedisTemplate<String,Element> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public String getName() {
        return "my-redis";
    }

    @Override
    public Object getNativeCache() {
        return this.redisTemplate;
    }

    @Override
    public Element get(Object key) {

        try {
            LOGGER.debug("Key is: {}", key);
            Object element = this.redisTemplate.opsForHash().get(REDIS_KEY, key);
            LOGGER.debug("element Object is: {}", element);
            return (element == null) ? null : (Element) element;
            //return (Element) this.redisTemplate.opsForHash().get(REDIS_KEY, key);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    @Override
    public void put(Element element) {
        this.redisTemplate.opsForHash().put(REDIS_KEY, element.key(), element);
    }

    @Override
    public void evict(Object key) {
        this.redisTemplate.opsForHash().delete(REDIS_KEY, key);  
    }

    @Override
    public void clear() {
        redisTemplate.execute((RedisCallback<Object>) connection -> {
            connection.flushDb();
            return null;
        });
    }
}

这是我试图放入实现 Serializable 的缓存中的 CacheElement 对象,如下所示:

public class CacheElement implements Element, Serializable {
.
.
.
}

当我尝试将对象放入缓存时,它失败并出现序列化失败的错误。我知道我的 RedisTemplate 存在一些问题,但我无法弄清楚。这是我收到的错误:

无法序列化;嵌套异常是 org.springframework.core.serializer.support.SerializationFailedException: 无法使用 DefaultSerializer 序列化对象;嵌套异常是 java.lang.IllegalArgumentException: DefaultSerializer 需要 Serializable 有效负载,但收到了 [io.gravitee.policy.cache.resource.CacheElement] 类型的对象

编辑

我正在尝试将 CacheElement 类的实例存储到 Redis 中:

public class CacheElement implements Element {

    private final String key;

    private final CacheResponse response;

    private int timeToLive = 0;

    public CacheElement(String key, CacheResponse response) {
        this.key = key;
        this.response = response;
    }

    public int getTimeToLive() {
        return timeToLive;
    }

    public void setTimeToLive(int timeToLive) {
        this.timeToLive = timeToLive;
    }

    @Override
    public Object key() {
        return key;
    }

    @Override
    public Object value() {
        return response;
    }

    @Override
    public int timeToLive() {
        return timeToLive;
    }
}

CacheResponse 对象包含 Buffer。

public class CacheResponse {

    private int status;

    private HttpHeaders headers;

    private Buffer content;

    public Buffer getContent() {
        return content;
    }

    public void setContent(Buffer content) {
        this.content = content;
    }

    public HttpHeaders getHeaders() {
        return headers;
    }

    public void setHeaders(HttpHeaders headers) {
        this.headers = headers;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}

我想序列化这个 CacheElement 对象并将其存储在 Redis 中。我也想在 get 操作时反序列化它。

我将不胜感激帮助解决此问题。正如我所提到的,我不是 Java 开发人员。我来自 C# 和视觉工作室世界。谢谢

标签: javajedisspring-data-redis

解决方案


请使用 Serializable 接口实现您的有效负载对象类


推荐阅读