如何在Java中反序列化JSON对象数组

如何在Java中反序列化JSON对象数组,java,arrays,json,jackson,deserialization,Java,Arrays,Json,Jackson,Deserialization,所以我习惯于从给定的API/端点获取JSON对象,例如: { "count": 5, "results": [ { "example": "test", "is_valid": true }, { "example": "test2", "is_valid": true } ] } 在扩展com.fasterxm

所以我习惯于从给定的API/端点获取JSON对象,例如:

{
    "count": 5,
    "results": [
        {
            "example": "test",
            "is_valid": true
        },
        {
            "example": "test2",
            "is_valid": true
        }
    ]
}
在扩展com.fasterxml.jackson.databind.deser.std.StdDeserializer的自定义反序列化程序中,我知道我可以像这样使用JsonParser对象来获取要处理的基本节点,即:

@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;
    }
}

我想我应该在提问之前写下单元测试,但显然你也可以用同样的方法来做。唯一的区别是基本节点是一个JsonArray,您必须迭代它。感谢所有关注此问题的人。

当响应是
JSON对象时
您可以使用默认的bean反序列化器。如果它是一个
JSON数组
,您可以将其读取为数组并手动创建响应对象。下面您可以找到用于注册自定义反序列化程序的示例自定义反序列化程序和
BeanDeserializerModifier
BeanDeserializerModifier
允许在
JSON
负载适合
POJO
型号时使用默认反序列化器:

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数组
payload打印:

Response{count=5, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}
Response{count=2, results=[Item{example='test', isValid=true}, Item{example='test2', isValid=true}]}

你能再发一些代码吗?什么是
jp
?如上所述,jp是JsonParser。我将继续为上下文添加更多代码。您好,我也在以类似的方式进行操作,就像我有一个json对象数组,但得到这个错误com.fasterxml.jackson.databind.JsonMappingException:(was java.io.IOException)(通过引用链:java.lang.Object[][0])↵