Json 自定义Jackson反序列化程序和数组
请注意:在这个网站上有很多关于如何使用自定义Jackson反序列化程序的问题…这个问题不是其中的一个!这些问题与在非常特殊的情况下使用反序列化程序有关,在此网站上没有任何问题/答案 这里使用Jackson进行JSON序列化的Spring引导。我有两个POJO,它们在@RequestBody HTTP请求实体中用于POST端点:Json 自定义Jackson反序列化程序和数组,json,spring-boot,jackson,deserialization,Json,Spring Boot,Jackson,Deserialization,请注意:在这个网站上有很多关于如何使用自定义Jackson反序列化程序的问题…这个问题不是其中的一个!这些问题与在非常特殊的情况下使用反序列化程序有关,在此网站上没有任何问题/答案 这里使用Jackson进行JSON序列化的Spring引导。我有两个POJO,它们在@RequestBody HTTP请求实体中用于POST端点: @JsonDeserialize(using = FizzDeserializer.class) public class Fizz { private String
@JsonDeserialize(using = FizzDeserializer.class)
public class Fizz {
private String name;
private String label;
private Integer code;
// Getters, setters & ctors
}
@JsonDeserialize(using = BuzzDeserializer.class)
public class Buzz {
private String id;
private String locale;
private Set<Fizz> fizzes;
// Getters, setters & ctors
}
@RestController
@RequestMapping("v1/data/buzzes")
public class BuzzController {
@PostMapping
public void updateBuzz(@RequestBody Buzz buzz) {
// do whatever
}
}
{
"id" : "12345-67890",
"locale" : "en_US",
"fizzes" : [
"foo",
"bar"
]
}
…其中foo和bar是两个不同的Fizz实例的fizzname。换句话说,我不希望客户端必须指定整个Fizz对象,只需将其名称指定为JSON字符串my app+DB保证Fizzes具有唯一的名称
因此,我使用自定义JsonDeserializer来完成所有这些映射:
public BuzzDeserializer extends JsonDeserializer<Buzz> {
Buzz deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode buzzNode = jsonParser.readValueAsTree();
String id = buzzNode.get("id");
String locale = buzzNode.get("locale");
// TODO: How to read "foo" and "bar" (etc.) into a Set<Fizz> instances?
Set<Fizz> fizzes = ???
new Buzz(id, locale, fizzes);
}
}
public FizzDeserializer extends JsonDeserializer<Fizz> {
private FizzDAO fizzDAO;
// Getters, setters & ctors...
Fizz deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode fizzNode = jsonParser.readValueAsTree();
// If I can get access to "foo"/"bar"/etc. string somehow, I can look up the Fizz using the DAO:
String fooBarEtcStr = ???
return fizzDAO.findFizzByName(fooBarEtcStr);
}
但是,我不确定如何将JSON fizzes数组读入这个反序列化器中的集合。有什么想法吗?根据对问题的评论,唯一的问题似乎是获取JSON数组。如果要查找的服务或DAO已在序列化程序中注入或提供,请尝试以下方法:
final JsonNode arr = buzzNode.get("fizzes");
if (arr.isArray()) {
final Set<Fizz> fizzes = Sets.newHashSetWithExpectedSize(arr.size());
for (JsonNode obj : arr) {
final String name = obj.asText();
Fizz fizz = // load from DAO
fizzes.add(fizz);
}
}
当然,这可以通过收集字符串值并只使用一个DAO调用来优化。另外,一些java8流可以减少代码的冗余。显然,您需要在反序列化程序中注入一个服务/DAO来按名称加载Fizzes。这里有一个关于如何进行的问题:是的,谢谢@msparer+1这正是我所做的,你看过上面的代码了吗?问题是如何将字符串名[foo,bar]的JSON数组解析到列表中。然后,我可以将该列表中的每个字符串传递到DAO中,以查找其各自的嘶嘶声。