2015-02-10 151 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 

希望它能帮助。