RedisTemplateシーケンス化StringRedisSerializerはStringのピットしかサポートできません

5259 ワード

  • プロジェクトではspring-data-redisパッケージのRedisTemplateクラスを使用してredis操作を行い、valueを構成するシーケンス化クラスではStringRedisSerializerを使用し、以下の通り:
  • private RedisTemplate buildRedisTemplate(JedisConnectionFactory connectionFactory) {
           RedisTemplate redisTemplate = new RedisTemplate<>();
           redisTemplate.setKeySerializer(new StringRedisSerializer());
           redisTemplate.setValueSerializer(new StringRedisSerializer());
           redisTemplate.setHashKeySerializer(new StringRedisSerializer());
           redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
           redisTemplate.setConnectionFactory(connectionFactory);
           return redisTemplate;
       }
    

    redisTemplate.setValueSerializer(new StringRedisSerializer());
  • StringRedisSerializerはStringタイプのvalueしか格納できません.doubleのような他のタイプのデータを格納すると、valueをredisに保存できません.Stringに移行する必要があります.
  • Double value = 12.0;
    BoundValueOperations valOps = redisTemplate.boundValueOps(key);
    valOps.set(value);
    
    Double value = 12.0;
    BoundValueOperations valOps = redisTemplate.boundValueOps(key);
    valOps.set(value.toString());
    

    StringRedisSerializerソースコードは、Stringとbyte[]の間でのみシーケンス化と逆シーケンス化を意味します.
    /**
     * Simple String to byte[] (and back) serializer. Converts Strings into bytes and vice-versa using the specified charset
     * (by default UTF-8).
     * 

    * Useful when the interaction with the Redis happens mainly through Strings. *

    * Does not perform any null conversion since empty strings are valid keys/values. * * @author Costin Leau */ public class StringRedisSerializer implements RedisSerializer { private final Charset charset; public StringRedisSerializer() { this(Charset.forName("UTF8")); } public StringRedisSerializer(Charset charset) { Assert.notNull(charset); this.charset = charset; } public String deserialize(byte[] bytes) { return (bytes == null ? null : new String(bytes, charset)); } public byte[] serialize(String string) { return (string == null ? null : string.getBytes(charset)); } }

  • ですので、Doubleタイプのデータを格納するにはJackson 2 JsonRedisSerializerに変更する必要があります.
  • redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    

    しかし、すぐに間違えました.
    org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized token 'NIO': was expecting 'null', 'true', 'false' or NaN
     at [Source: [B@6bb7cce7; line: 1, column: 7]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'NIO': was expecting 'null', 'true', 'false' or NaN
     at [Source: [B@6bb7cce7; line: 1, column: 7]
    	at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:73)
    	at org.springframework.data.redis.serializer.SerializationUtils.deserializeValues(SerializationUtils.java:50)
    	at org.springframework.data.redis.serializer.SerializationUtils.deserialize(SerializationUtils.java:58)
    	at org.springframework.data.redis.core.AbstractOperations.deserializeValues(AbstractOperations.java:202)
    	at org.springframework.data.redis.core.DefaultSetOperations.members(DefaultSetOperations.java:134)
    	at org.springframework.data.redis.core.DefaultBoundSetOperations.members(DefaultBoundSetOperations.java:91)
    

    前にシーケンス化して保存したデータを逆シーケンス化できなくなった.具体的には以下のようにmembersを呼び出してsetのデータを取得すると、逆シーケンス化できず、ピットはここにあり、
      set:
    BoundSetOperations setOps = redisTemplate.boundSetOps(key);
    setOps.add(symbol);
      set:
    BoundSetOperations setOps = redisTemplate.boundSetOps(key);
    return setOps.members();
    

    設計の初めに使用します.
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    

    複数のデータ型のストレージをサポートし、いくつかのデータを格納してから交換しないようにするには、履歴データを処理する必要があります.そうしないと、逆シーケンス化できません.Jackson 2 JsonRedisSerializerのソース:FastJSONを使用してシーケンス化と逆シーケンス化を行います.
    /**
     * {@link RedisSerializer} that can read and write JSON using Jackson's and Jackson Databind {@link ObjectMapper}.
     * 

    * This converter can be used to bind to typed beans, or untyped {@link java.util.HashMap HashMap} instances. * Note:Null objects are serialized as empty arrays and vice versa. * * @author Thomas Darimont * @since 1.2 */ public class Jackson2JsonRedisSerializer implements RedisSerializer { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private final JavaType javaType; private ObjectMapper objectMapper = new ObjectMapper(); ... }


    おすすめ:https://blog.csdn.net/jinzhencs/article/details/75123631 https://stackoverflow.com/questions/46233296/can-not-store-non-string-object-when-using-stringredisserializer-for-hashvaluese