2016-05-30 117 views
0

我需要解析数组数组。 这里是我当前的代码: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 ] 

回答

1

首先,您应该将您的数据模型与使用代码分开。我在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()); 
    } 
} 

的ChartList看起来像这样

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

谢谢,我无法更改json输入字符串的格式。我问是否有可能使解析结果变平? – edbond