2017-10-04 126 views
1

我有一些麻煩反序列化包含0的對象到許多可以包含特定值的字符串或字符串數​​組的子對象。GSON反序列化字符串或字符串數​​組

下面是一個例子JSON

{ 
"name": "process name", 
"tasks": [{ 
     "name": "task 1", 
     "fields": [{ 
       "name": "field 1", 
       "value": "123abc" 
      }, 
      { 
       "name": "field 2", 
       "value": ["value 1", "value 2"] 
      } 
     ] 
    }, 
    { 
     "name": "task 2", 
     "fields": [] 
    }] 
} 

我有一個Java實體設置來匹配這個結構是這樣的:

public class Process { 
    public Process() {} 

    public String name; 
    public Task[] tasks; 
} 

public class Task { 
    public Task() {} 

    public String name; 
    public Field[] fields; 
} 

public class Field { 
    public Field() field; 

    public String name; 
    public String value; 
} 

我反序列化像這樣:

static <T> T fetch(MyHttpRequest request, Class<T> entity) 
{ 
    String response = sendRequestAndParse(request); 
    if (response == null) { 
     log.debug(String.format("API response was null %n)")); 
     return null; 
    } 

    GsonBuilder gsonBuilder = new GsonBuilder(); 
    Gson gson = gsonBuilder.create(); 
    return gson.fromJson(response, entity); 
} 

我用動態類型,因爲除了Process以外,還有一些其他實體我使用了相同的方法。但我無法弄清楚如何處理字段值可以是字符串數組的字符串的情況。任何指針將不勝感激。

回答

1

可能是最簡單的選擇是使用自定義的串行器和解串並改變從StringList<String>value型這是基本的想法,你如何解決這個問題:

private static class MyJsonAdapter implements JsonSerializer<List<String>>, 
     JsonDeserializer<List<String>>{ 

    @Override 
    public JsonElement serialize(List<String> list, Type t, 
           JsonSerializationContext jsc) { 
     if (list.size() == 1) { 
      return jsc.serialize(list.get(0)); 
     } else { 
      return jsc.serialize(list); 
     } 
    } 
    @Override 
    public List<String> deserialize(JsonElement json, Type typeOfT, 
            JsonDeserializationContext jsc) 
      throws JsonParseException { 
     List<String> result; 

     if (json.isJsonArray()) { 
      result = jsc.deserialize(json, typeOfT); 
     }else { 
      result = new ArrayList<>(); 
      result.add((String) jsc.deserialize(json, String.class)); 
     } 
     return result; 
    } 
} 

田徑POJO

public static class Field { 
    public String name; 

    // Use @JsonAdapter(MyJsonAdapter.class) 
    // or register serializer and deserializer in 
    // new GsonBuilder().registerTypeAdapter(new MyJsonAdapter()) 
    @JsonAdapter(MyJsonAdapter.class) 
    public List<String> value; // need to change value type to list 
} 

Ps。如果你可以從Gson切換到Jackson,這個問題可以用1行代碼來解決。DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY

+0

謝謝你,這是非常有幫助的。我一直在尋找如何做到這一點幾天,我遇到的大多數文章都涉及到爲整個流程實體編寫自定義反序列化器,我知道必須有更好的方法。 – Austin