【问题标题】:How to display only specific field from nested JSON如何仅显示嵌套 JSON 中的特定字段
【发布时间】:2021-05-29 12:37:16
【问题描述】:

我有一个从中读取数据的嵌套 JSON。我想只取一个特定字段并在控制台中显示它。

为了在对象模型中映射我的 JSON,我创建了 3 个类 CarResponseCarCarValue

CarResponse.java

public class CarResponse {

    List<Car> car = new ArrayList<Car>();

    public List<Car> getCar() {
        return car;
    }

    public void setCar(List<Car> car) {
        this.car = car;
    }
   
    //Getters and Setters

   @Override
public String toString() {

    String str = "=================================\r\n";
    // Start of the day
    ZonedDateTime zdt = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
    StringBuilder sb = new StringBuilder();
    sb.append(zdt.toString()).append(System.lineSeparator());
    for (int i = 1; i <= 23; i++) {
        zdt = zdt.plusHours(1);
        sb.append(zdt.toString()).append(System.lineSeparator());
        for (Car ld : car) {
            str += "\t" + "Shop: " + ld.getShop() + "\r\n";
            str += "\t" + "Date: " + ld.getDate() + "\r\n";
            str += "\t" + "Values: " + ld.getValues() + "\r\n";
        }
        System.out.println(sb);
        return str;
    }
    return null;
}

Car.java

public class Car {

    private String shop;
    private String date;
    @JsonDeserialize(using = CustomDeserializer.class)
    private CarValues values;

    //Getters and Settrs  
 
    @Override
    public String toString() {
        String str = "=================================\r\n";
        str += "Shop: " + shop + "\r\n" +
                "Date: " + date + "\r\n";

        for(CarValue ld : values) {
            str += "\t" + "Name: " + ld.getName()+ "\r\n";
            str += "\t" + "Age: " + ld.getAge() + "\r\n";
            str += "\t" + "Country: " + ld.getCountry() + "\r\n";
        }
        return str;
    }
}

CarValue.java

public class CarValue {
    private String name;
    private String country;
    private Long age;
    
    //Getters and Setters and toString

我创建了自定义反序列化器以从 JSON 中获取 name 字段/键。

CustomDeserializer.java

public class CustomDeserializer extends JsonDeserializer {

    @Override
    public QuoteValue deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectCodec oc = p.getCodec();
        JsonNode node = oc.readTree(p);
        QuoteValue value =  new QuoteValue();
        value.setname(node.toString());
        return value;
    }

}

data.json

{
  "car": [
    {
      "shop": "Audi Germany",
      "date": 1573599600000,
      "values": [
        {
          "name": "Audi Xl",
          "age": "2020",
          "country": "Germany"
        },
        {
          "name": "Audi i",
          "age": "2021",
          "country": "France"
        },
        {
          "name": "Bmw Xl",
          "age": "2020",
          "country": "Spain"
        },
        {
          "name": "Citroen",
          "age": "1990",
          "country": "France"
        }
        ]
    }]
}

现在这个输出显示在控制台中:

2021-02-27T09:00+01:00[Europe/Zagreb]
    Shop: Audi
    Date: 1573599600000
    Values: QuoteValue{tLabel='[{"name":"Audi Xl","age":"2020","country":"Germany"},{"name":"Audi i","age":"2021","country":"France",{"name":"Bmw","age":"2020","country":"Spain"},{"name":"Citroen","age":"1990","country":"France",}]}

我想显示

2021-02-27T09:00+01:00[Europe/Zagreb]
        Date: 1573599600000
        Values:[{"name":"Audi Xl"},{"name":"Audi i"},{"name":"Bmw"},{"name":"Citroen"}]}

【问题讨论】:

  • 反序列化意味着将对象从 JSON 转换回 Java。你需要一个自定义的序列化器。
  • 好的,对不起,我忘了写这是我第一次这样做 :) 你能举个例子,我的代码的序列化是什么样的?
  • 您是否尝试过从CarValue 类中删除不必要的字段?
  • 是的,但我收到错误Unrecognized field "value", not marked as ignorable (one known property: "name"])

标签: java json spring-boot jackson json-deserialization


【解决方案1】:

您可以使用注释来注释可序列化的类

    @JsonIgnoreProperties(value = { "intValue" })

您可以在其中添加多个要在序列化中忽略的字段。

无需编写额外代码:)

你可以在这里参考完整的解释

https://www.baeldung.com/jackson-ignore-properties-on-serialization

【讨论】:

  • 感谢您的回答。我已经尝试应用它和@JsonIgnore,但它不起作用。
【解决方案2】:

也许如果你像这样修改一些类:

Car:将values 更改为列表(您没有提供有关任何名为CarValuesQuoteValue 的类的信息)并删除不必要的toString

public class Car {

    private String shop;
    private String date;
    private List<CarValue> values;  // <- a list
}

CarValue :添加toString 覆盖:

public class CarValue {
    private String name;
    private String country;
    private Long age;

    @Override
    public String toString() {
        return "{\"name\": \"" + name + "\"}";
    }
}

使用此设置,它应该或多或少地按预期工作,并且您不需要自定义反序列化程序。假设你像这样阅读你的 json :

CarResponse carResponse = objectMapper.readValue(json, CarResponse.class)

如果您仍然需要JsonDeserializer,请使用参数化类型,例如:

public class CustomQuoteDeserializer extends JsonDeserializer<QuoteValue> {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多