[英]How to Deserialize Array of JSON Objects in Java
所以我习惯于从给定的 API/端点获取 JSON 对象,例如:
{
"count": 5,
"results": [
{
"example": "test",
"is_valid": true
},
{
"example": "test2",
"is_valid": true
}
]
}
并在扩展 com.fasterxml.jackson.databind.deser.std 的自定义解串器中。 StdDeserializer ,我知道我可以像这样使用 JsonParser object 来使基本节点正常工作,即:
@Override
public ResultExample deserialize(JsonParser jp, DeserializationContext ctxt) {
JsonNode node = jp.getCodec().readTree(jp);
JsonNode count = node.get("count");
// code to put parsed objects into a ResultExample object...
}
但是,我刚刚遇到了一个 API ,它只返回一个 JSON 对象数组,例如:
[
{
"example": "test",
"is_valid": true
},
{
"example": "test2",
"is_valid": true
},
]
所以,我不相信我可以像以前一样解析这个。 使用 Jackson 解析这个的正确方法是什么?
这可能会帮助您:
import java.io.IOException;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String json = "[\r\n" + " {\r\n" + " \"example\": \"test\",\r\n" + " \"is_valid\": true\r\n"
+ " },\r\n" + " {\r\n" + " \"example\": \"test2\",\r\n" + " \"is_valid\": true\r\n"
+ " }\r\n" + "]";
Example[] ex = mapper.readValue(json, Example[].class);
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "example", "is_valid" })
class Example {
@JsonProperty("example")
private String example;
@JsonProperty("is_valid")
private Boolean isValid;
public String getExample() {
return example;
}
@JsonProperty("example")
public void setExample(String example) {
this.example = example;
}
@JsonProperty("is_valid")
public Boolean getIsValid() {
return isValid;
}
@JsonProperty("is_valid")
public void setIsValid(Boolean isValid) {
this.isValid = isValid;
}
}
当响应是JSON Object
,您可以使用默认的 bean 解串器。 如果它是JSON Array
,您可以将其读取为数组并手动创建响应 object。 您可以在下面找到示例自定义反序列化器和用于注册自定义反序列化器的BeanDeserializerModifier
。 当JSON
有效负载适合POJO
model 时, BeanDeserializerModifier
允许使用默认解串器:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getBeanClass() == Response.class) {
return new ResponseJsonDeserializer((BeanDeserializerBase) deserializer);
}
return super.modifyDeserializer(config, beanDesc, deserializer);
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.readValue(jsonFile, Response.class));
}
}
class ResponseJsonDeserializer extends BeanDeserializer {
private final BeanDeserializerBase baseDeserializer;
protected ResponseJsonDeserializer(BeanDeserializerBase src) {
super(src);
this.baseDeserializer = src;
}
@Override
public Response deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.currentToken() == JsonToken.START_OBJECT) {
return (Response) baseDeserializer.deserialize(p, ctxt);
}
if (p.currentToken() == JsonToken.START_ARRAY) {
CollectionType collectionType = ctxt.getTypeFactory().constructCollectionType(List.class, Item.class);
JsonDeserializer<Object> deserializer = ctxt.findRootValueDeserializer(collectionType);
List<Item> results = (List<Item>) deserializer.deserialize(p, ctxt);
Response response = new Response();
response.setCount(results.size());
response.setResults(results);
return response;
}
throw MismatchedInputException.from(p, Response.class, "Only object or array!");
}
}
class Response {
private int count;
private List<Item> results;
// getters, setters, toString
}
class Item {
private String example;
@JsonProperty("is_valid")
private boolean isValid;
// getters, setters, toString
}
上面的代码JSON Object
有效载荷打印:
Response{count=5, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}
对于JSON Array
有效载荷打印:
Response{count=2, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}
我想我应该在问问题之前就写好单元测试,但显然你可以用同样的方式来做。 唯一的区别是基节点是一个 JsonArray ,您必须对其进行迭代。 感谢所有对此进行调查的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.