[英]How to delegate to default deserialization in custom deserializer in Jackson?
Suppose I am writing custom serialization for some class, but would like to process one of its field with default methods. 假设我正在为某个类编写自定义序列化,但是希望使用默认方法处理其中一个字段。
How to do that? 怎么做?
While serializing we have JsonGenerator#writeObjectField()
. 序列化时我们有JsonGenerator#writeObjectField()
。
But what is corresponding method for deserialization? 但是反序列化的相应方法是什么?
Regard the code below: 请注意以下代码:
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<MyOuterClass> {
@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<MyOuterClass> {
@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
}
}
How to implement MyOuterDeserializer
? 如何实现MyOuterDeserializer
?
The DeserializationContext
offers these tools. DeserializationContext
提供了这些工具。
After checking the field name for "inner"
, move to the next token, the beginning of the JSON object and use the DeserializationContext
to deserialize the JSON object into a MyInnerClass
object. 检查字段名称"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);
The javadoc states javadoc说
Convenience method that may be used by composite or container deserializers, for reading one-off values contained (for sequences, it is more efficient to actually fetch deserializer once for the whole collection). 复合或容器反序列化器可以使用的便捷方法,用于读取包含的一次性值(对于序列,实际上为整个集合提取一次反序列化器更有效)。
Careful while using the DeserializationContext
. 使用DeserializationContext
小心。 Don't try to recursively deserialize types for which you have have registered custom deserializers. 不要尝试递归反序列化已注册自定义反序列化器的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.