You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从嵌套JSON中仅显示指定字段

问题梳理与代码修正

咱们一步步来修正代码,帮你实现从嵌套JSON中仅提取name字段,并输出你想要的格式。目前你的代码存在几个关键问题,我逐个给你解决:

1. 修正对象模型的字段类型

你的Car类里values字段定义为CarValues,但JSON中的values是数组结构,应该对应List<CarValue>类型。同时要调整自定义反序列化器的适配类型:

修改后的Car.java

public class Car {
    private String shop;
    private String date;
    @JsonDeserialize(using = CustomDeserializer.class)
    private List<CarValue> values; // 修正为List<CarValue>,匹配JSON数组结构

    // Getters and Setters
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder("=================================\r\n");
        str.append("Shop: ").append(shop).append("\r\n")
           .append("Date: ").append(date).append("\r\n");
        for(CarValue ld : values) {
            str.append("\t").append("Name: ").append(ld.getName()).append("\r\n");
            // 按需只输出name字段,其他字段可以注释掉
        }
        return str.toString();
    }
}

2. 修复自定义反序列化器逻辑

原来的反序列化器返回类型错误,也没有正确遍历JSON数组提取name。修改后让它专门处理数组,只提取每个元素的name字段:

修改后的CustomDeserializer.java

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CustomDeserializer extends JsonDeserializer<List<CarValue>> {
    @Override
    public List<CarValue> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        ObjectCodec oc = p.getCodec();
        JsonNode node = oc.readTree(p);
        List<CarValue> valueList = new ArrayList<>();
        
        // 遍历JSON数组,逐个提取name字段
        if (node.isArray()) {
            for (JsonNode itemNode : node) {
                CarValue value = new CarValue();
                value.setName(itemNode.get("name").asText()); // 仅保留name字段
                valueList.add(value);
            }
        }
        return valueList;
    }
}

3. 调整CarResponse的toString输出逻辑

原来的toString方法有逻辑bug:循环刚执行一次就return,导致输出不完整,格式也不符合预期。调整后让它输出你想要的格式:

修改后的CarResponse.java

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

public class CarResponse {
    List<Car> car = new ArrayList<>();
    
    public List<Car> getCar() { return car; }
    public void setCar(List<Car> car) { this.car = car; }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        // 输出当前时区的起始时间(和你示例格式一致)
        ZonedDateTime zdt = LocalDate.now().atStartOfDay(ZoneId.systemDefault());
        sb.append(zdt.toString()).append(System.lineSeparator());

        for (Car ld : car) {
            sb.append("Date: ").append(ld.getDate()).append(System.lineSeparator());
            // 格式化输出仅包含name的数组
            sb.append("Values:[");
            for (int i = 0; i < ld.getValues().size(); i++) {
                CarValue cv = ld.getValues().get(i);
                sb.append("{\"name\":\"").append(cv.getName()).append("\"}");
                // 最后一个元素不加逗号
                if (i != ld.getValues().size() - 1) {
                    sb.append(",");
                }
            }
            sb.append("]}").append(System.lineSeparator());
        }
        return sb.toString();
    }
}

4. 测试代码示例

假设你用Jackson解析JSON,测试代码可以这样写:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;

public class Main {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        CarResponse response = mapper.readValue(new File("data.json"), CarResponse.class);
        System.out.println(response.toString());
    }
}

最终输出效果

运行后就能得到你期望的控制台输出:

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

内容的提问来源于stack exchange,提问作者user9347049

火山引擎 最新活动