假设我有以下POJO:
class Pojo { String s; Object o; Map<String, String> m; }
而且在运行时,我想要除一个属性外的所有属性的默认序列化/反序列化。通常,我要在序列化时用数据库中的字段ID替换字段,这与其他问题类似。
例如,我要替换o为从外部映射获得的字符串(例如:object1<=>“ 123”和object2<=>“ 456”):
o
object1
object2
Pojo
o = object1
我知道模块是做到这一点的一种方法,但是我不确定如何使用它们,同时又为不需要更改的属性保留了自动BeanSerializer / Deserializer。
有人可以举一个例子(甚至是人为的)还是一种替代方法?
编辑
为了更清楚一点,我可以对Mixins进行以下操作:
ObjectMapper mapper = new ObjectMapper(MongoBsonFactory.createFactory()); mapper.addMixInAnnotations(Pojo.class, PojoMixIn.class); ObjectReader reader = mapper.reader(Pojo.class); DBEncoder dbEncoder = DefaultDBEncoder.FACTORY.create(); OutputBuffer buffer = new BasicOutputBuffer(); dbEncoder.writeObject(buffer, o);
使用以下Mixin:
abstract class PojoMixIn { @JsonIgnore Object o; }
然后将所需的字符串添加到JSON内容。但是我需要在编译时知道是该o字段需要替换,而我不需要。
我认为@JsonSerialize,@JsonDeserialize这就是您所需要的。这些注释使您可以控制特定字段的序列化/反序列化。这个问题展示了将它们组合为一个注释的优雅方法。
@JsonSerialize
@JsonDeserialize
UPD。 对于这种复杂的情况,您可以看一下BeanSerializerModifier/BeanDeserializerModifier类。这个想法是BeanSerializer/BeanDeserializer使用特定字段的自定义逻辑来修改常规,然后让基本实现来做其他事情。稍后再发布示例。
BeanSerializerModifier/BeanDeserializerModifier
BeanSerializer/BeanDeserializer
UPD2。 如我所见,一种方法可能是使用changePropertiesmethod并分配自己的序列化程序。
changeProperties
UPD3。 更新了自定义序列化程序的工作示例。反序列化可以类似的方式进行。
UPD 4。 更新了具有完全自定义序列化/反序列化的示例。(我用过 jakson-mapper-asl-1.9.8 )
public class TestBeanSerializationModifiers { static final String PropertyName = "customProperty"; static final String CustomValue = "customValue"; static final String BaseValue = "baseValue"; // Custom serialization static class CustomSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { String customValue = CustomValue; // someService.getCustomValue(value); jgen.writeString(customValue); } } static class MyBeanSerializerModifier extends BeanSerializerModifier { @Override public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BasicBeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { for (int i = 0; i < beanProperties.size(); i++) { BeanPropertyWriter beanPropertyWriter = beanProperties.get(i); if (PropertyName.equals(beanPropertyWriter.getName())) { beanProperties.set(i, beanPropertyWriter.withSerializer(new CustomSerializer())); } } return beanProperties; } } // Custom deserialization static class CustomDeserializer extends JsonDeserializer<Object> { @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // serialized value, 'customValue' String serializedValue = jp.getText(); String baseValue = BaseValue; // someService.restoreOldValue(serializedValue); return baseValue; } } static class MyBeanDeserializerModifier extends BeanDeserializerModifier { @Override public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BasicBeanDescription beanDesc, BeanDeserializerBuilder builder) { Iterator<SettableBeanProperty> beanPropertyIterator = builder.getProperties(); while (beanPropertyIterator.hasNext()) { SettableBeanProperty settableBeanProperty = beanPropertyIterator.next(); if (PropertyName.equals(settableBeanProperty.getName())) { SettableBeanProperty newSettableBeanProperty = settableBeanProperty.withValueDeserializer(new CustomDeserializer()); builder.addOrReplaceProperty(newSettableBeanProperty, true); break; } } return builder; } } static class Model { private String customProperty = BaseValue; private String[] someArray = new String[]{"one", "two"}; public String getCustomProperty() { return customProperty; } public void setCustomProperty(String customProperty) { this.customProperty = customProperty; } public String[] getSomeArray() { return someArray; } public void setSomeArray(String[] someArray) { this.someArray = someArray; } } public static void main(String[] args) { SerializerFactory serializerFactory = BeanSerializerFactory .instance .withSerializerModifier(new MyBeanSerializerModifier()); DeserializerFactory deserializerFactory = BeanDeserializerFactory .instance .withDeserializerModifier(new MyBeanDeserializerModifier()); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializerFactory(serializerFactory); objectMapper.setDeserializerProvider(new StdDeserializerProvider(deserializerFactory)); try { final String fileName = "test-serialization.json"; // Store, "customValue" -> json objectMapper.writeValue(new File(fileName), new Model()); // Restore, "baseValue" -> model Model model = objectMapper.readValue(new File(fileName), Model.class); } catch (IOException e) { e.printStackTrace(); } } }