我想反序列化一个JSON有效负载,它代表一个可以是字符串(未展开)或对象(展开)的字段:
示例有效负载未展开:仅发送一个字符串值,表示包含id。
{
"id" : "777424881071",
"category" : "/category/12",
"title" : "ACADEMY DINOSAUR",
"description" : "A Epic Drama of ...",
}
示例有效负载已展开:已发送相应的ID:
{
"id" : "777424881071",
"category" : {
"id" : "12",
"name" : "Children"
},
"title" : "ACADEMY DINOSAUR",
"description" : "A Epic Drama of ...",
}
在java中,这可以用这样的类型表示:
public class ExpandableField<T> {
private String id;
private T expandedObject;
public ExpandableField(String id, T expandedObject) {
this.id = id;
this.expandedObject = expandedObject;
}
}
有关条带java客户端的完整示例,请参阅ExpandableField。
我想知道如何为杰克逊写一个JsonDeserializer<ExpandableField<?>>
。
public class ExpandableFieldDeserializer extends JsonDeserializer<ExpandableField<?>> {
@Override
public ExpandableField<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken token = p.getCurrentToken();
if (token == JsonToken.VALUE_STRING) {
return new ExpandableField<>(p.getValueAsString(), null);
}
else if (token == JsonToken.START_OBJECT) {
//TODO deserialize object and compute id
return new ExpandableField<>(id, object);
}
return null;
}
}
我目前的解决方案是加载当前树并使用一种小方法硬编码相应的类:private Class<?> computeType(JsonNode node)
。
public class ExpandableFieldDeserializer extends JsonDeserializer<ExpandableField<?>> {
@Override
public ExpandableField<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken token = p.getCurrentToken();
if (token == JsonToken.VALUE_STRING) {
return new ExpandableField<>(p.getValueAsString(), null);
}
else if (token == JsonToken.START_OBJECT) {
ObjectCodec codec = p.getCodec();
JsonNode node = codec.readTree(p);
String id = null;
if (node.has("id")) {
id = node.asText();
}
Class<?> typeClass = computeType(node);
Object object = codec.treeToValue(node, typeClass);
return new ExpandableField<>(id, object);
}
return null;
}
private Class<?> computeType(JsonNode node) {
//...
}
}
我更喜欢更有活力的东西。
作为比较,使用 gson 库,可以在方法签名中访问该类型:
deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
((ParameterizedType) typeOfT).getActualTypeArguments()[0]
,context
能够使用context.deserialize(json, t)
反序列化对象。
请在此处查看完整示例:ExpandableFieldDeserializer
与杰克逊有什么相似之处?