2015-02-10 149 views
3

有一個問題here與我的問題類似,但並不完全是我正在尋找的。Gson - 將JSON解析爲Object時忽略json字段

我已經從一個Web服務的JSON響應,讓我們說this JSON response

{ 
    "routes" : [ 
     { 
     "bounds" : { 
      "northeast" : { 
       "lat" : 45.5017123, 
       "lng" : -73.5672184 
      }, 
      "southwest" : { 
       "lat" : 43.6533103, 
       "lng" : -79.3827675 
      } 
     }, 
     "copyrights" : "Dados do mapa ©2015 Google", 
     "legs" : [ 
      { 
       "distance" : { 
        "text" : "541 km", 
        "value" : 540536 
       }, 
       "duration" : { 
        "text" : "5 horas 18 min.", 
        "value" : 19058 
       }, 
       "end_address" : "Montreal, QC, Canada", 
       "end_location" : { 
        "lat" : 45.5017123, 
        "lng" : -73.5672184 
       }, 
       "start_address" : "Toronto, ON, Canada", 
       "start_location" : { 
        "lat" : 43.6533103, 
        "lng" : -79.3827675 
       }, 
       (...) 

在這個JSON我的distance對象只是感興趣。我的問題是,我怎麼能忽略所有其他領域?

我試圖從legs開始構建我的對象,因爲它是從根distance開始的第一個非重複對象名稱。

這是我的目標:

public class MyObject { 

    public ArrayList<Distance> legs; 

    public static class Distance { 
     public String text; 
     public String value; 
    } 
} 

ArrayList legs總是null

我該如何做到這一點?忽略假裝的json字段左側的字段。

+0

'distance'是名爲'legs'的JSON數組內的JSON對象中的鍵值對的名稱。 – 2015-02-10 02:54:49

+0

@SotiriosDelimanolis是的,我知道。但是我沒有得到你評論的背景。你能解釋一下嗎? – dazito 2015-02-10 03:03:47

+1

你有一個名爲'legs'的'ArrayList '字段。這將映射到包含匹配'Distance'類格式的JSON對象的JSON數組。你錯過了一層。實際的JSON有一個名爲'legs'的JSON數組,但其中的JSON對象具有名爲'distance'的字段。 – 2015-02-10 03:05:25

回答

6

我認爲Gson的哲學是將Json結構映射到對象圖。所以在你的情況下,我可能會創建所有需要的java對象來正確映射json結構。除此之外,也許有一天你會需要一些其他的迴應信息,所以進化會更容易。類似的東西(我認爲正確的方法):

class RouteResponse { 
    private List<Route> routes; 
} 
class Route { 
    private List<Bound> bounds; 
    private String copyrights; 
    private List<Leg> legs; 
} 
class Leg { 
    private Distance distance; 
    private Duration duration; 
    private String endAddress; 
    ... 
} 
class TextValue { 
    private String text; 
    private String value; 
} 
class Distance extends TextValue { 
} 
// And so on 

而且我會用一個ExclusionStrategy有輕的物體,並只有我感興趣的領域這聽起來好像正確的方式做。那。

現在,如果您確實想要檢索距離列表,我相信您可以使用自定義TypeAdapterTypeAdapterFactory來做到這一點。

類似的東西(:-)糟糕的方法):

的對象映射響應:

public class RouteResponse { 

    private List<Distance> distances; 

    // add getters/setters 
} 

public class Distance { 

    private String text; 
    private String value; 

    // add getters/setters 
} 

工廠實例化我們的適配器(至Gson對象的引用,所以該適配器可以檢索委託):

public class RouteResponseTypeAdapterFactory implements TypeAdapterFactory { 

    @Override 
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 
     if (type.getRawType() == RouteResponse.class) { 
      return (TypeAdapter<T>)new RouteResponseTypeAdapter(gson); 
     } 
     return null; 
    } 
} 

而且適配器類型:此實現將首先在JSON文檔解組到然後將檢索所需的JsonObject s來創建通過代理Distance對象(對不好的代碼,很快寫入)。

public class RouteResponseTypeAdapter extends TypeAdapter<RouteResponse> { 

    private final TypeAdapter<JsonElement> jsonElementTypeAdapter; 
    private final TypeAdapter<Distance> distanceTypeAdapter; 

    public RouteResponseTypeAdapter(Gson gson) { 
     this.jsonElementTypeAdapter = gson.getAdapter(JsonElement.class); 
     this.distanceTypeAdapter = gson.getAdapter(Distance.class); 
    } 

    @Override 
    public void write(JsonWriter out, RouteResponse value) throws IOException { 
     throw new UnsupportedOperationException("Not implemented"); 
    } 

    @Override 
    public RouteResponse read(JsonReader jsonReader) throws IOException { 
     RouteResponse result = new RouteResponse(); 
     List<Distance> distances = new ArrayList<>(); 
     result.setDistances(distances); 
     if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) { 
      JsonObject responseObject = (JsonObject) jsonElementTypeAdapter.read(jsonReader); 
      JsonArray routes = responseObject.getAsJsonArray("routes"); 
      if (routes != null) { 
       for (JsonElement element:routes) { 
        JsonObject route = element.getAsJsonObject(); 
        JsonArray legs = route.getAsJsonArray("legs"); 
        if (legs != null) { 
         for (JsonElement legElement:legs) { 
          JsonObject leg = legElement.getAsJsonObject(); 
          JsonElement distanceElement = leg.get("distance"); 
          if (distanceElement != null) { 
           distances.add(distanceTypeAdapter.fromJsonTree(distanceElement)); 
          } 
         } 
        } 
       } 
      } 
     } 
     return result; 
    } 
} 

最後,你可以分析你的JSON文檔:

String json = "{ routes: [ ....."; // Json document 
    Gson gson = new GsonBuilder().registerTypeAdapterFactory(new RouteResponseTypeAdapterFactory()).create(); 
    RouteResponse response = gson.fromJson(json, RouteResponse.class); 
    //response.getDistances() should contain the distances 

希望它能幫助。