Java 如何创建POJO来处理包含元素数组和元素数组的JSON数据
我们有一个场景,其中一个字段有两个不同的值。我们希望使用相同的Java 如何创建POJO来处理包含元素数组和元素数组的JSON数据,java,json,scala,jackson,jackson2,Java,Json,Scala,Jackson,Jackson2,我们有一个场景,其中一个字段有两个不同的值。我们希望使用相同的POJO解析所有JSON。下面您可以找到以下2个JSON有效负载: { "values": [ [ { "name": "item_name", "value": "pool" } ], [ { "name": "item_name", "value": "Mob" } ] ],
POJO
解析所有JSON。下面您可以找到以下2个JSON
有效负载:
{
"values": [
[
{
"name": "item_name",
"value": "pool"
}
],
[
{
"name": "item_name",
"value": "Mob"
}
]
],
"name": "lines"
}
以及:
目前,若我指定如下POJO,则第二个json抛出异常
class ValuesModel extends Serializable {
@BeanProperty
var values: List[List[ValueModel]] = _
}
class ValuesModel extends Serializable {
@BeanProperty
var values: List[ValueModel] = _
}
若我指定如下POJO,则第一个json抛出异常
class ValuesModel extends Serializable {
@BeanProperty
var values: List[List[ValueModel]] = _
}
class ValuesModel extends Serializable {
@BeanProperty
var values: List[ValueModel] = _
}
有没有办法创建一个
POJO
来同时解析两个JSON,而不是捕获异常并用另一个模式进行解析?我正在使用Jackson
进行解析。在这种情况下,您需要处理多个JSON
模式,并能够将其反序列化为实现自定义反序列化器和实现所有所需场景所需的同一POJO
模型
下面您可以在Java
中找到如何反序列化JSON
有效负载的示例:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.fasterxml.jackson.databind.type.SimpleType;
import com.fasterxml.jackson.databind.util.TokenBuffer;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./src/main/resources/test.json");
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(jsonFile, ValuesModel.class));
}
}
class ValuesModelJsonDeserializer extends JsonDeserializer<List<ValueModel>> {
@Override
public List<ValueModel> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
final JsonDeserializer<Object> deserializer = ctxt.findRootValueDeserializer(SimpleType.constructUnsafe(ValueModel.class));
final JsonNode root = p.readValueAsTree();
// If node is a JSON object
if (root.isObject()) {
return Collections.singletonList(deserialize(p.getCodec(), root, deserializer, ctxt));
}
if (!root.isArray()) {
// value is null or primitive
return Collections.emptyList();
}
return StreamSupport.stream(root.spliterator(), false)
.map(this::unwrap)
.filter(node -> !node.isMissingNode())
.map(node -> deserialize(p.getCodec(), node, deserializer, ctxt))
.collect(Collectors.toList());
}
private JsonNode unwrap(JsonNode node) {
if (node.isArray()) {
if (node.isEmpty()) {
return MissingNode.getInstance();
}
return node.iterator().next();
}
return node;
}
private ValueModel deserialize(ObjectCodec codec, JsonNode value, JsonDeserializer<Object> valueDeser, DeserializationContext ctxt) {
try (JsonParser jsonParser = createNestedParser(codec, value)) {
return (ValueModel) valueDeser.deserialize(jsonParser, ctxt);
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
private JsonParser createNestedParser(ObjectCodec codec, JsonNode value) throws IOException {
TokenBuffer buffer = new TokenBuffer(codec, false);
codec.writeTree(buffer, value);
JsonParser parser = buffer.asParser();
parser.nextToken();
return parser;
}
}