仅反序列化 Java 中 JSON 数组中的一个对象

Deserialize only one object from JSON array in Java

我收到来自 API 的 JSON 回复:

{
  "value": [{
    "some-field": "blah-blah",
    ...
  }]
}

数组中总是有一个对象,所以我不想像这样存储一个 pojo:

public class Foo {
    private List<InnerClass> value;
}

但像这样:

public class Foo {
    private String field1;
    private String field2;
...
}

如何为它创建自定义解串器?

我尝试了以下方法:

public class CustomDeserializer extends StdDeserializer<Foo> {

    public CustomDeserializer(Class<Foo> clazz) {
        super(clazz);
    }

    public CustomDeserializer() {
        this(null);
    }

    @Override
    public Foo deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
 
        JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
        String s = jsonNode.get("value").get(0).toString();
        Foo obj = new ObjectMapper().readValue(s, Foo.class);
        return obj;
    }
}

但是有一些循环问题,它不起作用。

问题出在您自定义解串器中的这一行:

Foo obj = new ObjectMapper().readValue(s, Foo.class);

当你这样做时,你的 CustomDeserializer 被第二次调用,但现在有一个不同格式的 json,它无法处理它。更准确地说,它找不到名为 value 的 属性。所以你有两个选择来修复它:

  1. 创建 Foo 并手动设置字段
public class CustomDeserializer extends StdDeserializer<Foo> {

    public CustomDeserializer(Class<Foo> clazz) {
        super(clazz);
    }

    public CustomDeserializer() {
        this(null);
    }

    @Override
    public Foo deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
        JsonNode valueNode = jsonNode.get("value").get(0);
        Foo obj = new Foo();
        obj.setField1(valueNode.get("field1").asText());
        obj.setField2(valueNode.get("field2").asText());
        return obj;
    }
}
  1. 要保持​​ CustomDeserializer 不变,您需要将反序列化器 注册到 ObjectMapper 实例,它会实际反序列化初始 json 并且不要在 Foo 上使用注释来指定反序列化器。
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Foo.class, new CustomDeserializer());
mapper.registerModule(module);

作为旁注,如果您选择第二个选项,Foo obj = new ObjectMapper().readValue(s, Foo.class); - 每次反序列化时,此行都会创建 ObjectMapper 的新实例。例如,最好将 ObjectMapper 的实例保留为静态字段。