如何仅显示嵌套 JSON 中的特定字段

Posted

技术标签:

【中文标题】如何仅显示嵌套 JSON 中的特定字段【英文标题】:How to display only specific field from nested 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: QuoteValuetLabel='["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"]) 【参考方案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> 

【讨论】:

以上是关于如何仅显示嵌套 JSON 中的特定字段的主要内容,如果未能解决你的问题,请参考以下文章

如何仅向graphene-django中的用户个人资料所有者显示特定字段?

ReactJS:仅更新嵌套状态对象中的特定字段[重复]

如何从 Bigquery 中的这个嵌套 JSON 类型列中查询特定的内容

如何使用 node 和 express.js 仅发送 json 响应中的特定字段?

如何从JSON加载特定数据并显示UICollectionView?

如何从 webview 中的 json responseString 获取特定方法