假设我正在为某个类编写自定义序列化,但是希望使用默认方法处理其中一个字段.
怎么做?
虽然序列化我们有JsonGenerator#writeObjectField()
.
但是反序列化的相应方法是什么?
请注意以下代码:
import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.io.IOException; import java.util.Objects; public class TryDelegate { public static class MyOuterClassSerializer extends JsonSerializer{ @Override public void serialize(MyOuterClass value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { gen.writeStartObject(); gen.writeObjectField("inner", value.getInner()); gen.writeEndObject(); } } public static class MyOuterClassDeserializer extends JsonDeserializer { @Override public MyOuterClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { MyOuterClass ans = new MyOuterClass(); JsonToken token; token = p.getCurrentToken(); if( token != JsonToken.START_OBJECT ) { throw new JsonParseException("Start object expected", p.getCurrentLocation()); } if( !"inner".equals(p.nextFieldName() ) ) { throw new JsonParseException("'inner; field expected", p.getCurrentLocation()); } MyInnerClass inner = null;// how to desrialize inner from here with default processing??? ans.setInner(inner); token = p.nextToken(); if( token != JsonToken.END_OBJECT ) { throw new JsonParseException("End object expected", p.getCurrentLocation()); } return ans; } } public static class MyInnerClass { private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public String toString() { return "{\"value\":" + value + "}"; } } @JsonDeserialize(using = MyOuterClassDeserializer.class) @JsonSerialize(using = MyOuterClassSerializer.class) public static class MyOuterClass { private MyInnerClass inner; public MyInnerClass getInner() { return inner; } public void setInner(MyInnerClass inner) { this.inner = inner; } @Override public String toString() { return "{\"inner\":" + Objects.toString(inner) + "}"; } } public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); String string; MyInnerClass inner = new MyInnerClass(); inner.setValue(12); MyOuterClass outer = new MyOuterClass(); outer.setInner(inner); string = mapper.writeValueAsString(outer); System.out.println(string); MyOuterClass outer2 = mapper.readValue(string, MyOuterClass.class); System.out.println(outer2); // inner was not deserialized } }
如何实施MyOuterDeserializer
?
在DeserializationContext
提供这些工具.
检查字段名称后"inner"
,移动到下一个标记,JSON对象的开头,并使用DeserializationContext
将JSON对象反序列化为MyInnerClass
对象.
if (!"inner".equals(p.nextFieldName())) { throw new JsonParseException("'inner; field expected", p.getCurrentLocation()); } p.nextToken(); // consumes the field name token MyInnerClass inner = ctxt.readValue(p, MyInnerClass.class);
javadoc说
复合或容器反序列化器可以使用的便捷方法,用于读取包含的一次性值(对于序列,实际上为整个集合提取一次反序列化器更有效).
使用时要小心DeserializationContext
.不要尝试递归反序列化已注册自定义反序列化器的类型.