简体   繁体   中英

Spring RestTemplate Jackson Deserialize Array of Arrays

I'm using Spring RestTemplate to pull data from an API that returns an un-named array of arrays in the following format:

[
    [
        1518230040,
        8863.96,
        8876.95,
        8863.96,
        8876.94,
        1.81986441
    ],
    [
        1518229980,
        8851.03,
        8862.53,
        8853.79,
        8862.53,
        2.95533163
    ],
    [
        1518229920,
        8853.79,
        8855.3,
        8855.29,
        8853.8,
        3.0015851299999996
    ]
]

The indices in the nested arrays represent the following properties of a Candlestick :

0 => time
1 => low
2 => high
3 => open
4 => close
5 => volume

For example, in the first nested array, the time of the Candlestick is 1518230040, the low is 8863.96, the high is 8876.95, the open is 8863.96, the close is 8876.94, and the volume is 1.81986441.

I'd like to map these nested array elements to Candlestick objects. Below is my Candlestick class.

import java.math.BigDecimal;

public class Candlestick {
    private long time;

    private BigDecimal low;

    private BigDecimal high;

    private BigDecimal open;

    private BigDecimal close;

    private BigDecimal volume;

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public BigDecimal getLow() {
        return low;
    }

    public void setLow(BigDecimal low) {
        this.low = low;
    }

    public BigDecimal getHigh() {
        return high;
    }

    public void setHigh(BigDecimal high) {
        this.high = high;
    }

    public BigDecimal getOpen() {
        return open;
    }

    public void setOpen(BigDecimal open) {
        this.open = open;
    }

    public BigDecimal getClose() {
        return close;
    }

    public void setClose(BigDecimal close) {
        this.close = close;
    }

    public BigDecimal getVolume() {
        return volume;
    }

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

    @Override
    public String toString() {
        return "Candle [time=" + time + ", low=" + low + ", high=" + high + ", open=" + open + ", close=" + close
                + ", volume=" + volume + "]";
    }
}

How can I map the nested arrays to Candlestick objects using Spring RestTemplate and Jackson?

You need to do the following;

  1. Write a Custom Deserializer for Candlestick pojo Configure

    public class CandlestickDeserializer extends StdDeserializer<Candlestick> { public CandlestickDeserializer() { this(null); } public CandlestickDeserializer(Class<?> vc) { super(vc); } @Override public Item deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); // Read the Array or Arrays return new Candlestick(// Return with correct values read from Array); } }
  2. ObjectMapper to use that custom Deserializer

    // This will get the Spring ObjectMapper singleton instance. @Autowired ObjectMapper mapper; @PostConstruct public void init() throws Exception { SimpleModule module = new SimpleModule(); module.addDeserializer(Candlestick.class, new CandlestickDeserializer()); mapper.registerModule(module); } Candlestick readValue = mapper.readValue(json, Candlestick.class);

Designing a Custom Deserializer would be a reasonable solution to this problem. But mapping array to an oject seems to be a tricky job. Keeping @shazin's idea as base, Custom Deserializer that maps array of arrays into list of objects can be written as follows:

public class CStickListDeserializer extends StdDeserializer<ArrayList<Candlestick>> { 

    public CStickListDeserializer() { 
        this(null); 
    } 

    public CStickListDeserializer(Class<?> c) { 
        super(c); 
    }

    @Override
    public ArrayList<Candlestick> deserialize(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException {

        Candlestick cs ;
        ArrayList<Candlestick> cList = new ArrayList<Candlestick>();
        BigDecimal[][] a = jp.readValueAs(BigDecimal[][].class);
        for(BigDecimal[] a1 : a){
            cs = new Candlestick();
            cs.setTime(a1[0].longValue());
            cs.setLow(a1[1]);
            cs.setHigh(a1[2]);
            cs.setOpen(a1[3]);
            cs.setClose(a1[4]);
            cs.setVolume(a1[5]); 
            cList.add(cs);
        }
             return cList;
    }
}

Usage:

     ObjectMapper om = new ObjectMapper();
     SimpleModule mod = new SimpleModule();
     mod.addDeserializer(ArrayList.class, new CStickListDeserializer());
     om.registerModule(mod);
     ArrayList<Candlestick> CandlestickList = om.readValue(json, ArrayList.class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM