2012-07-31 56 views
1

我要解析一個JSON看起來有時GSON解析數據是串有時有有時對象

school_name:「馬丁高中」, 領袖:{ FIRST_NAME:「奧斯汀」, 姓氏:「萬豪」, }

,有時甚至

school_name: 「馬丁高中」, 領導: 「/領導者/ 3434」。

我試圖看看是否有一個示例反序列化器可以處理「領導者」sometiems是一個字符串,有時是一個對象。但找不到任何。

這與gson可能嗎?

回答

2

您只需爲您的Leader實施TypeAdapter。在read(JsonReader in)使用JsonReader.peek()來找出即將到來的內容並將其讀取並將其轉換爲Leader。它應該是相當微不足道的。

我做了一個練習....

public class GsonStringOrObjectDemo { 
    @EqualsAndHashCode 
    private static class Leader { 
     String firstName; 
     String lastName; 
    } 
    private static class LeaderAdapter extends TypeAdapter<Leader> { 
     @Override 
     public void write(JsonWriter out, Leader value) throws IOException { 
      if (useString) { 
       out.value(value.firstName + ":" + value.lastName); 
      } else { 
       out.beginObject(); 
       out.name("firstName"); 
       out.value(value.firstName); 
       out.name("lastName"); 
       out.value(value.lastName); 
       out.endObject(); 
      } 
      useString = !useString; 
     } 

     @Override 
     public Leader read(JsonReader in) throws IOException { 
      final Leader result = new Leader(); 
      final JsonToken type = in.peek(); 
      switch (type) { 
      case BEGIN_OBJECT: 
       in.beginObject(); 
       while (true) { 
        final String key = in.nextName(); 
        final String value = in.nextString(); 
        if (key.equals("firstName")) result.firstName = value; 
        else if (key.equals("lastName")) result.lastName = value; 
        else throw new JsonParseException("Unexpected key in Leader: " + key); 
        if (in.peek() == JsonToken.END_OBJECT) break; 
       } 
       in.endObject(); 
       return result; 
      case STRING: 
       final String string = in.nextString(); 
       final int pos = string.indexOf(':'); 
       result.firstName = string.substring(0, pos); 
       result.lastName = string.substring(pos+1); 
       return result; 
      default: 
       throw new JsonParseException("Expected string or object for Leader, got: " + type); 
      } 
     } 

     private boolean useString; 
    } 

    public static void main(String[] args) throws Exception { 
     final Gson gson = new GsonBuilder().registerTypeAdapter(Leader.class, new LeaderAdapter()).setPrettyPrinting().create(); 
     final Leader[] leaders = new Leader[10]; 
     for (int i=0; i<leaders.length; ++i) { 
      leaders[i] = new Leader(); 
      leaders[i].firstName = "First" + i; 
      leaders[i].lastName = "Last" + i; 
     } 
     final String json = gson.toJson(leaders); 
     final Leader[] leaders2 = gson.fromJson(json, Leader[].class); 
     Assert.assertTrue(Arrays.equals(leaders, leaders2)); 
    } 
} 
+0

寫一個單獨的類,在我的建設者加入吧.. builder.registerTypeAdapter(Leader.class,新LeaderAdapter());但適配器的讀取或寫入永遠不會被調用..任何想法? – 2012-07-31 20:27:12

+0

所以它被調用與領導者是一個對象,但從來沒有被調用時,它是一個字符串 – 2012-07-31 21:23:38

+0

這很奇怪..看看我更新的答案,它的工作原理。在Java中,你必須始終使用一個對象,但我希望你能這樣做。 – maaartinus 2012-07-31 21:47:44