请注意:此网站上有很多关于如何使用自定义杰克逊反序列化程序的问题......这个问题不是还有一个问题!这个问题与在非常独特的情况下使用反序列化器有关(在本网站上没有任何问题/答案!)。
Spring Boot使用Jackson进行JSON序列化。我有两个POJO在@RequestBody
(HTTP请求实体)中用于POST端点:
@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
}
}
我希望HTTP客户端能够将以下JSON发布到此端点:
{
"id" : "12345-67890",
"locale" : "en_US",
"fizzes" : [
"foo",
"bar"
]
}
...其中"foo"
和“bar
”是两个不同Fizz#names
个实例的Fizz
。换句话说,我不希望客户端必须指定整个 Fizz
对象,只需将其name
指定为JSON字符串(我的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
数组读入此反序列化器中的Set<Fizz>
。 有什么想法吗?
答案 0 :(得分:1)
从对问题的评论中得出,唯一的问题似乎是获取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);
}
}
这当然可以通过收集String
值并仅使用一个DAO
来优化。还有一些java8流可以使代码更简洁。