java - Jackson:解析数组的数组

标签 java json jackson

我需要解析数组的数组。 这是我当前的代码:

package android.app;

import android.support.annotation.Nullable;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
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.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.TypeFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 */
public class ChartData {
    private static final String MSFT_JSON = "[[\"2015-05-27\",47.61,27335600]]";
    private static final ObjectMapper mapper = new ObjectMapper();

    @Nullable
    public static ChartList msftPrice() {
        try {
            ChartList[] chartList = mapper.readValue(MSFT_JSON, ChartList[].class);
            // ChartEntry[] chartEntries = mapper.convertValue(MSFT_JSON, ChartEntry[].class);
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @JsonDeserialize(using = ChartEntryDeserializer.class)
    public static class ChartEntry {
        public String date;
        public Float price;
        public Integer volume;

        public ChartEntry(String date, Float price, Integer volume) {
            this.date = date;
            this.price = price;
            this.volume = volume;
        }
    }

    private static class ChartEntryDeserializer extends JsonDeserializer<ChartEntry> {
        public ChartEntryDeserializer() {
        }

        @Override @JsonCreator
        public ChartEntry deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            String date = p.getCodec().readValue(p, String.class);
            Float price = p.getCodec().readValue(p, Float.class);
            Integer volume = p.getCodec().readValue(p, Integer.class);

            return new ChartEntry(date, price, volume);
        }
    }

    @JsonDeserialize(using=ChartListDeserializer.class)
    public static class ChartList {
        public ChartEntry[] chartEntries;
    }

    private static class ChartListDeserializer extends JsonDeserializer<ChartList> {
        @Override
        public ChartList deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            ChartList result = new ChartList();
            result.chartEntries = p.readValuesAs(ChartEntry[].class).next();
            return result;
        }
    }
}

它确实返回类似的内容

chartList array of type ChartList [
  0: { chartEntries: [ChartEntry object]
]

我怎样才能让它变得更扁平,就像:

chartList: [ array of chartEntries ]

最佳答案

首先,您应该将数据模型与使用代码分开。我在下面的 JUnit 测试中完成了此操作以演示其用法。数据模型分为两个单独的类:ChartList 和 ChartEntry。

生成的 JSON 字符串如下所示:

{"chartList":[{"date":"2015-05-27","price":47.61,"volume":27335600},{"date":"2015-05-28","price":47.71,"volume":27335700}]}

这是测试类

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestClass {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    public void testObjToJson() throws Exception {
        ChartList list = new ChartList();
        list.addEntry(new ChartEntry("2015-05-27", 47.61f, 27335600));
        list.addEntry(new ChartEntry("2015-05-28", 47.71f, 27335700));
        System.out.println( mapper.writeValueAsString(list));
    }

    @Test
    public void testJsonToObj() throws Exception {
        final String JSON = "{\"chartList\":[{\"date\":\"2015-05-27\",\"price\":47.61,\"volume\":27335600},{\"date\":\"2015-05-28\",\"price\":47.71,\"volume\":27335700}]}";
        ChartList list = mapper.readValue(JSON, ChartList.class);
        assertEquals( 2, list.getChartList().size());
    }
}

图表列表看起来像这样

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class ChartList {

    private List<ChartEntry> chartList = new ArrayList<>();

    @JsonIgnore
    public void addEntry(ChartEntry entry) {
        chartList.add(entry);
    }

    public List<ChartEntry> getChartList() {
        return chartList;
    }

    public void setChartList(List<ChartEntry> chartList) {
        this.chartList = chartList;
    }
}

ChartEntry 看起来像这样

public class ChartEntry {

    private String date;
    private Float price;
    private Integer volume;

    public ChartEntry() {
        // Needed for JSON-to-Object parsing
    }

    public ChartEntry(String date, Float price, Integer volume) {
        this.date = date;
        this.price = price;
        this.volume = volume;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Integer getVolume() {
        return volume;
    }

    public void setVolume(Integer volume) {
        this.volume = volume;
    }
}

关于java - Jackson:解析数组的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37530159/

相关文章:

java - Maven 故障安全插件。复制资源

java - 将 DICOM 转换为 JPEG 时出错

java - Eclipse : The import org. apache无法解析

java - Jackson 序列化 - 忽略不设置的值,但提供显式设置为 null 的值

java - 在 Web 服务中接受多种 JSON 格式

java - 子类是否具有父类的所有属性和方法?

java - 在自定义反序列化器中将 JsonNode 转换为 POJO

java - 如何迭代 json 对象数组(gson)

java - 无法在 linkedin Rest API 中获取教育详细信息

java - 使用 Android 将图像读取为字节数组:skImageDecoder::Factory 返回 null