没有直接的方法可以告诉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 中的代码