2016-10-10 63 views
0

試想一下,如果我有以下的JSON怎麼辦條件GSON反序列化的默認值

{"game":"football", "people":"elevent"} 
{"game":"badminton", "people":"two"} 

我班如下

class Sport { 
    String game; 
    String people; 
} 

我可以做我的Json的反序列化如下

Sport mySport = Gson().fromJson(json, Sport.class); 

但是,如果我的JSON只是

{"game":"football"} 
{"game":"badminton"} 

我希望它自動初始化people爲「elevent」或「two」,等待第一個字段。有沒有一種方法可以配置我的GsonBuilder()以在反序列化過程中自動實現?

+1

http://stackoverflow.com/questions/30216317/setting-default-value-to-a-variable-when-deserializing-using-gson可以幫助這一點。 –

+0

默認值很簡單,通過實例化'String people =「elevent」'。但我有兩個和三個值設置初始值懸而未決。所以如果可能的話,我寧願自定義反序列化。 – Elye

回答

1

你可以創建一個自定義JsonDeserializer

public class SportDeserializer implements JsonDeserializer<Sport> { 
    @Override 
    public Sport deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException { 
     JsonObject jsonObject = (JsonObject) json; 

     String game = jsonObject.get("game").getAsString(); 
     JsonElement nullablePeople = jsonObject.get("people"); 
     String people = nullablePeople == null ? null : nullablePeople.getAsString(); 

     if (people == null || people.isEmpty()) { 
      if (game.equals("football")) { 
       people = "elevent"; 
      } 
      else if (game.equals("badminton")) { 
       people = "two"; 
      } 
     } 

     Sport sport = new Sport(); 
     sport.game = game; 
     sport.people = people; 

     return sport; 
    } 
} 

然後使用定製JsonDeserializer

GsonBuilder gsonBuilder = new GsonBuilder(); 
gsonBuilder.registerTypeAdapter(Sport.class, new SportDeserializer()); 
Gson gson = gsonBuilder.create(); 
Sport sport = gson.fromJson(jsonString, Sport.class); 
+0

謝謝韋恩。你的回答最適合我的問題。我沒有使用它,因爲我的實際情況比上面的Json更復雜,它具有Json的各種層次結構,並且兩個字段在同一層次結構中彼此不接近。因此我使用下面的解決方案。但是,我很好地回答了我的問題,所以我仍然給你打個招呼。謝謝!! – Elye

0

下面我的答案是不是最好的這個問題,因爲我簡化了問題,另一個答案會更好地解決這個問題。

但是對於更復雜的情況,我的答案在下面會有所幫助。它基本上是在GSon轉換後進行後期處理。

我終於用Gson convert後處理了。

class Sport implements PostProcessingEnabler.PostProcessable { 
    String game; 
    String people; 

    @Override 
    public void gsonPostProcess() { 
     // The below is something simple. 
     // Could have more complicated scneario. 
     if (game.equals("football")) { 
      people = "elevant"; 
     } else if (game.equals("badminton")) { 
      people = "two"; 
     } 
    } 
} 

class PostProcessingEnabler implements TypeAdapterFactory { 
    public interface PostProcessable { 
     void gsonPostProcess(); 
    } 

    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 
     final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 

     return new TypeAdapter<T>() { 
      public void write(JsonWriter out, T value) throws IOException { 
       delegate.write(out, value); 
      } 

      public T read(JsonReader in) throws IOException { 
       T obj = delegate.read(in); 
       if (obj instanceof PostProcessable) { 
        ((PostProcessable) obj).gsonPostProcess(); 
       } 
       return obj; 
      } 
     }; 
    } 
} 

致敬去https://blog.simplypatrick.com/til/2016/2016-03-02-post-processing-GSON-deserialization/