我的JSON结构如下:
{
"id" : "123",
"name" : [ {
"stuff" : [ {
"id" : "234",
"name" : "Bob"
}, {
"id" : "345",
"name" : "Sally"
} ]
} ]
}
我想映射到以下数据结构:
我的界面1
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface1.class)
@JsonDeserialize(as = ImmutableMyInterface1.class)
public interface MyInterface1 {
String id();
@JsonDeserialize(using = MyInterface1Deserializer.class)
List<MyInterface2> name();
}
MyInterface2
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface2.class)
@JsonDeserialize(as = ImmutableMyInterface2.class)
public interface MyInterface2 {
@JsonDeserialize(using = StuffDeserializer.class)
Map<String, MyInterface3> stuff();
}
MyInterface3
@Value.Immutable
@JsonSerialize(as = ImmutableMyInterface3.class)
@JsonDeserialize(as = ImmutableMyInterface3.class)
public interface MyInterface3 {
String id();
String name();
}
我正在使用ObjectMapperreadValue(stringWithJson,MyInterface1.class)
将此JSON映射到MyInterface1,它应继续沿链向下链接到MyInterface3。当我在MyInterface2中使用列表时,该设置有效List<MyInterface3> name();
但是,我希望这是一个映射,而不是列表,理想情况下,以内部JSON中的“ id”为键。这将允许我使用以下语法获取值:MyInterface1.get(0).MyInterface2.get("id1").name();
问题是,当尝试创建自定义StuffDeserializer.class时,出现错误: Can not deserialize instance of com.foo.ImmutableMyInterface2$Json out of START_ARRAY token
尝试做时:
public Map<String, MyInterface3> deserialize(JsonParser jsonParser, DeserializationContext ctxt)
throws IOException {
MyInterface2 foo = Unmarshaller.OBJECT_MAPPER.readValue(jsonParser, MyInterface2.class); // error here
...
我认为这是因为Jackson期望“ stuff”是JSON数组的List'原因。将此JSON反序列化为使用内部JSON的值作为键的映射的最佳方法是什么?
我将创建一个自定义JsonDeserializer
来映射id
并映射name
到地图中:
public class StringHashMapValueDeserializer extends JsonDeserializer<HashMap<String, String>>{
@Override
public HashMap<String, String> deserialize(JsonParser parser, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
HashMap<String, String> ret = new HashMap<String, String>();
ObjectCodec codec = parser.getCodec();
TreeNode node = codec.readTree(parser);
if (node.isArray()){
for (JsonNode n : (ArrayNode)node){
JsonNode id = n.get("id");
if (id != null){
JsonNode name = n.get("name");
ret.put(id.asText(), name.asText());
}
}
}
return ret;
}
}
然后,我将stuff
使用反序列化器创建具有注释属性的简单bean :
@Getter
@Setter
public class Name {
@JsonDeserialize(using = StringHashMapValueDeserializer.class)
Map<String, String> stuff;
@Override
public String toString() {
return "Name [stuff=" + stuff + "]";
}
}
外型:
@Getter
@Setter
public class OuterType {
String id;
List<Name> name;
@Override
public String toString() {
return "OuterType [id=" + id + ", stuff=" + name + "]";
}
}
反序列化:
ObjectMapper mapper = new ObjectMapper();
OuterType response;
response = mapper.readValue(json, OuterType.class);
System.out.println(response);
System.out.println(response.getName().get(0).getStuff().get("234"));
控制台输出:
OuterType [id=123, stuff=[Name [stuff={234=Bob, 345=Sally}]]]
Bob
希望能帮助到你。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句