Redis
 sql >> база данни >  >> NoSQL >> Redis

GenericJackson2JsonRedisSerializer Игнориране на клас и атрибут

Няма директен начин да кажете на GenericJackson2JsonRedisSerializer да игнорирате някои полета и да преведете клас A до B , можете да приложите каквато искате стратегия за десериализация.

Един прост пример може да бъде, че регистрирате своите полета за съпоставяне и игнориране, когато искате да извършите преобразуване на тип.

// Adapted from spring data redis
public class RqueueRedisSerDes implements RedisSerializer<Object> {
    private ObjectMapper mapper;

    @AllArgsConstructor
    @Getter
    class Dataum {
      Class<?> tgtClass;
      String[] ignorableProperties;
    }

    private Map<Class<?>, Dataum> classMap = new ConcurrentHashMap<>();

    RqueueRedisSerDes() {
      this.mapper = new ObjectMapper();
      this.mapper =
          mapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer()));
      this.mapper = mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
      this.mapper = mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
    }

    public void addClassMap(Class<?> source, Class<?> tgt, String[] ignorableProperties) {
      classMap.put(source, new Dataum(tgt, ignorableProperties));
    }

    @Override
    public byte[] serialize(Object source) throws SerializationException {
      if (source == null) {
        return SerializationUtils.EMPTY_ARRAY;
      }
      try {
        return mapper.writeValueAsBytes(source);
      } catch (JsonProcessingException e) {
        throw new SerializationException("Could not write JSON: " + e.getMessage(), e);
      }
    }

    @Override
    public Object deserialize(byte[] source) throws SerializationException {
      if (SerializationUtils.isEmpty(source)) {
        return null;
      }
      try {
        Object object = mapper.readValue(source, Object.class);
        for (Entry<Class<?>, Dataum> entry : classMap.entrySet()) {
          if (ClassUtils.isAssignable(entry.getKey(), object.getClass())) {
            Dataum dataum = entry.getValue();
            Object tgt = dataum.getTgtClass().newInstance();
            BeanUtils.copyProperties(object, tgt, dataum.getIgnorableProperties());
            return tgt;
          }
        }
        return object;
      } catch (Exception ex) {
        throw new SerializationException("Could not read JSON: " + ex.getMessage(), ex);
      }
    }

    private static class NullValueSerializer extends StdSerializer<NullValue> {

      private static final long serialVersionUID = 211020517180777825L;
      private final String classIdentifier;

      NullValueSerializer() {
        super(NullValue.class);
        this.classIdentifier = "@class";
      }

      @Override
      public void serialize(
          NullValue value, JsonGenerator jsonGenerator, SerializerProvider provider)
          throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField(classIdentifier, NullValue.class.getName());
        jsonGenerator.writeEndObject();
      }
    }
  }

Дефинирайте клас, който ще имплементира RedisSerializer<Object> използвайте този клас в RedisConnectionFactory, за да сериализирате/десериализирате стойности.

class SerializerTest{      
  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public static class First {
    private String attribute1;
    private String attribute2;
    private String attribute3;
  }
  @Data
  @ToString
  public static class Second {
    private Integer attribute1;
    private String attribute2;
    private String attribute4;
  }

  public static void main(String[] args) {
    RqueueRedisSerDes serDes = new RqueueRedisSerDes();
    // ignore attribute1 due to different type
    serDes.addClassMap(First.class, Second.class, new String[]{"attribute1"});
    First first = new First("1", "2", "3");
    byte[] out = serDes.serialize(first);
    Second second = (Second) serDes.deserialize(out);
    System.out.println(second);
  }
}

Току-що промених код от моята Repo Rqueue




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Каква е най-добрата стратегия за синхронизиране на Redis данни с MySQL?

  2. Използване на клиент StackExchange.Redis с Redis клъстер

  3. вземете текущата дата и час в lua в redis

  4. Използване на nginx за обслужване на съдържание директно от кеша на redis

  5. Как мога да преглеждам/разглеждам стойностите, съхранени в Redis