gpt4 book ai didi

java - 基于 Jackson 中另一个字段值的条件字段要求?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:22:13 31 4
gpt4 key购买 nike

考虑一个包含一个字符串和两个数组的 JSON 表示。例如,

{
"type" : "A",
"ListA" : []
"ListB" : [3, 4, 5]
}

在上面的例子中,type 是必填字段,但是 ListAListB有条件反序列化所必需的基于 type 的值。换句话说,仅当 type 具有值 A 时才需要 ListA 并且仅当 时才需要 ListB type 有一个值 B

目前,我在 Jackson 和 Java 工作,我已经能够通过如下创建 POJO 来实现强制要求 type 字段:

public class Example {
@JsonProperty(required = true)
String type;

// getter and setter auto-generated

但我不能将另一个 @JsonProperty(required = true) 附加到 ListAListB,因为它取决于类型

如何根据 type 的值有条件地要求 ListAListB 进行反序列化?

此外,我将执行额外的检查,例如 ListAListB 是否为空数组 (size == 0) 或不是。

最佳答案

您可以使用自定义反序列化器来实现它。

定义模型

您的示例类如下:

public class Example {

private String type;
private List<Integer> listA;
private List<Integer> listB;

// Getters and setters omitted
}

创建自定义反序列化器

您的自定义反序列化器可能如下所示:

public class ExampleDeserializer extends StdDeserializer<Example> {

private static final String TYPE_A = "A";
private static final String TYPE_B = "B";

public ExampleDeserializer() {
super(Example.class);
}

@Override
public Example deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {

ObjectMapper mapper = (ObjectMapper) p.getCodec();
JsonNode tree = mapper.readTree(p);

Example example = new Example();

JsonNode typeNode = tree.get("type");
if (typeNode == null || typeNode.asText().isEmpty()) {
throw ctxt.mappingException("\"type\" is required");
}
example.setType(typeNode.asText());

switch (typeNode.asText()) {

case TYPE_A:
ArrayNode listANode = (ArrayNode) tree.get("ListA");
if (listANode == null || listANode.size() == 0) {
throw ctxt.mappingException(
"\"ListA\" is required when \"type\" is \"" + TYPE_A + "\"");
}
example.setListA(createList(listANode));
break;

case TYPE_B:
ArrayNode listBNode = (ArrayNode) tree.get("ListB");
if (listBNode == null || listBNode.size() == 0) {
throw ctxt.mappingException(
"\"ListB\" is required when \"type\" is \"" + TYPE_B + "\"");
}
example.setListB(createList(listBNode));
break;

default:
throw ctxt.mappingException(
"\"type\" must be \"" + TYPE_A + "\" or \"" + TYPE_B + "\"");
}


return example;
}

private List<Integer> createList(ArrayNode arrayNode) {
List<Integer> list = new ArrayList<Integer>();
for (JsonNode node : arrayNode) {
list.add(node.asInt());
}
return list;
}
}

注册自定义反序列化器

将上面定义的自定义反序列化器注册到您的 ObjectMapper:

SimpleModule module = new SimpleModule("ExampleDeserializer", 
new Version(1, 0, 0, null, "com.example", "example-deserializer"));

ExampleDeserializer exampleDeserializer = new ExampleDeserializer();
module.addDeserializer(Example.class, exampleDeserializer);

ObjectMapper mapper = new ObjectMapper()
.registerModule(module)
.enable(SerializationFeature.INDENT_OUTPUT);

测试您的自定义反序列化器

使用自定义序列化器:

String json = "{\"type\":\"A\",\"ListA\":[1,2,3]}";
Example example = mapper.readValue(json, Example.class);

关于java - 基于 Jackson 中另一个字段值的条件字段要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38840659/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com