0

I need to parse array of arrays. Here is my current code:

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;
        }
    }
}

It does returns something like

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

how can I make it more flatten to be like:

chartList: [ array of chartEntries ]

?

1 Answer 1

1

First, you should separate your data model from your usage code. I've done this below in a JUnit test to demonstrate the usage. The data model is split into two separate classes: ChartList and ChartEntry.

The resulting JSON string looks like this:

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

Here's the test class

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());
    }
}

The ChartList looks like this

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;
    }
}

The ChartEntry looks like this

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;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I can't change the format of json input string. I asked if it possible to flatten result of parsing?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.