GSON - JSON解析到对象时,忽略JSON领域 [英] Gson - ignore json fields when parsing JSON to Object

查看:210
本文介绍了GSON - JSON解析到对象时,忽略JSON领域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有是这里一个问题相似,我的问题,但不正是我要找的。

我已经从web服务的JSON响应,让我们说<一href=\"http://maps.googleapis.com/maps/api/directions/json?origin=Toronto&destination=Montreal&sensor=false\"相对=nofollow>这个JSON响应

  {
   路线:[
      {
         界限:{
            东北:{
               纬度:45.5017123,
               LNG:-73.5672184
            },
            西南:{
               纬度:43.6533103,
               LNG:-79.3827675
            }
         },
         版权:Dados做地图©2015谷歌
         腿:
            {
               距离:{
                  文:541公里
                  值:540536
               },
               持续时间:{
                  文:5 horas 18分钟。
                  值:19058
               },
               END_ADDRESS:蒙特利尔,加拿大
               END_LOCATION:{
                  纬度:45.5017123,
                  LNG:-73.5672184
               },
               START_ADDRESS:多伦多,加拿大
               START_LOCATION:{
                  纬度:43.6533103,
                  LNG:-79.3827675
               },
               (......)

在此JSON我在距离对象只是感兴趣。我的问题是,我怎么能忽略所有的其他领域?

我试图建立我的对象从腿开始,因为它是从的第一个非重复的对象名称距离到根。

下面是我的目标:

 公共类为MyObject {    公众的ArrayList&LT;距离和GT;双腿;    公共静态类的距离{
        公共字符串文本;
        公共字符串值;
    }
}

ArrayList的腿总是

我怎样才能做到这一点?忽略字段从pretended JSON场左侧。


解决方案

我认为GSON的理念是将JSON结构映射到对象图。所以你的情况我可能会创建所有需要的Java对象正确映射JSON结构。另外的,也许有一天你会需要响应的其他一些信息,所以这将是容易做的演变。类似的东西(适当的方式,我认为):

 类RouteResponse {
    私人列表&LT;路线和GT;路线;
}
Route类{
    私人列表&LT;&约束GT;界限;
    私人字符串版权;
    私人列表&LT;&腿GT;双腿;
}
一流的腿{
    私人距离距离;
    私人时间期限;
    私人字符串endAddress;
    ...
}
类TextValue {
    私人字符串文本;
    私人字符串值;
}
距离类扩展TextValue {
}
// 等等

和我会用一个<一个href=\"http://google-gson.google$c$c.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html\"相对=nofollow> ExclusionStrategy 有灯光对象,并只有我感兴趣的领域。这听起来好像正确的方式做到这一点。

现在,如果你真的想只检索距离的名单,我相信你能做到这一点与自定义的 TypeAdapter 和<一个href=\"http://google-gson.google$c$c.com/svn/trunk/gson/docs/javadocs/com/google/gson/TypeAdapterFactory.html\"相对=nofollow> TypeAdapterFactory 。

类似的东西(坏的方式: - )):

的对象映射响应:

 公共类RouteResponse {    私人列表&LT;距离和GT;距离;   //添加getter / setter方法
}公共类距离{    私人字符串文本;
    私人字符串值;   //添加getter / setter方法
}

这是我们的实例化适配器工厂(与在 GSON 对象的引用,因此适配器可以检索委托):

 公共类RouteResponseTypeAdapterFactory实现TypeAdapterFactory {    @覆盖
    公众&LT; T&GT; TypeAdapter&LT; T&GT;创建(GSON GSON,TypeToken&LT; T&GT;类型){
        如果(type.getRawType()== RouteResponse.class){
            回报(TypeAdapter&LT; T&GT;)新RouteResponseTypeAdapter(GSON);
        }
        返回null;
    }
}

和类型的适配器:此实现会先解组JSON文档到 JsonElement 取值树,然后将检索所需的的JSONObject s到委托创建距离对象(抱歉坏code,迅速写)。

 公共类RouteResponseTypeAdapter扩展TypeAdapter&LT; RouteResponse&GT; {    私人最终TypeAdapter&LT; JsonElement&GT; jsonElementTypeAdapter;
    私人最终TypeAdapter&LT;距离和GT; distanceTypeAdapter;    公共RouteResponseTypeAdapter(GSON GSON){
        this.jsonElementTypeAdapter = gson.getAdapter(JsonElement.class);
        this.distanceTypeAdapter = gson.getAdapter(Distance.class);
    }    @覆盖
    公共无效写入(JsonWriter出来,RouteResponse值)抛出IOException
        抛出新UnsupportedOperationException异常(未实现);
    }    @覆盖
    公共RouteResponse读(JsonReader jsonReader)抛出IOException
        RouteResponse结果=新RouteResponse();
        清单&LT;距离和GT;距离=新的ArrayList&LT;&GT;();
        result.setDistances(距离);
        如果(jsonReader.peek()== JsonToken.BEGIN_OBJECT){
            JSONObject的responseObject =(JSONObject的)jsonElementTypeAdapter.read(jsonReader);
            JsonArray路线= responseObject.getAsJsonArray(路线);
            如果(路线!= NULL){
                对于(JsonElement元素:路由){
                    JSONObject的路线= element.getAsJsonObject();
                    JsonArray腿= route.getAsJsonArray(腿);
                    如果(腿!= NULL){
                        对于(JsonElement legElement:双腿){
                            JSONObject的腿= legElement.getAsJsonObject();
                            JsonElement distanceElement = leg.get(距离);
                            如果(distanceElement!= NULL){
                                distances.add(distanceTypeAdapter.fromJsonTree(distanceElement));
                            }
                        }
                    }
                }
            }
        }
        返回结果;
    }
}

最后,你可以分析你的JSON文档:

  JSON字符串={路线:[.....; // JSON文档
    GSON GSON =新GsonBuilder()registerTypeAdapterFactory(新RouteResponseTypeAdapterFactory())创建()。
    RouteResponse响应= gson.fromJson(JSON,RouteResponse.class);
    //response.getDistances()应该包含的距离

希望它帮助。

There is a question here that is similar to my question but not exactly what I'm looking for.

I've a JSON response from a webservice, let's say 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
               }, 
               (...)

In this JSON I' just interested on the distance object. My question is, how can I ignore all the other fields?

I tried to build my object starting from legs, as it is the first non repetitive object name from distance to the root.

Here's my object:

public class MyObject {

    public ArrayList<Distance> legs;

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

but the ArrayList legs is always null.

How can I accomplish this? Ignore fields to the left from the pretended json field.

解决方案

I think that the philosophy of Gson is to map the Json structure to an objects graph. So in your case I would probably create all the needed java objects to map correctly the json structure. In addition of that, maybe one day you will need some other information of the response, so it will be easier to do the evolution. Something like that (the proper way I think):

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

And I would use an ExclusionStrategy to have light objects and to have only the fields I'm interested in. It sounds to me like the proper way to do that.

Now if you really want to retrieve only the list of distances, I'm sure you can do that with a custom TypeAdapter and TypeAdapterFactory.

Something like that (the bad way :-)):

The objects to map the response:

public class RouteResponse {

    private List<Distance> distances;

   // add getters / setters
}

public class Distance {

    private String text;
    private String value;

   // add getters / setters
}

The factory that instantiates our adapter (With a reference to the Gson object, so the adapter can retrieve delegates) :

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;
    }
}

And the type adapter: this implementation will first unmarshall the Json document to a JsonElements tree and then will retrieve the needed JsonObjects to create through the delegate the Distance objects (sorry for the bad code, quickly written).

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;
    }
}

Finally, you can parse your json document:

    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

Hope it helps.

这篇关于GSON - JSON解析到对象时,忽略JSON领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆