【问题标题】:GSON Ignore missing values from JSON stringGSON 忽略 JSON 字符串中的缺失值
【发布时间】:2015-11-20 01:17:29
【问题描述】:

我在我的 Android 应用中使用 GSON。目前,我正在设置一个方法,该方法包含一个名为“followed”的 JSON 字符串中的值。 JSON字符串中的一项包含followed,第二个字符串不包含。我使用 Realm 来持久化唯一的对象,这样你就可以看到它被覆盖了。

这里有 2 个 json 字符串作为示例进行比较:

{"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","zip":"19007","county":"Bucks County","apt_no":"","latitude":"40.1012666","longitude":"-74.855304","profile_picture":"uploads/thumbnails/2014/06/07/16/1402165202_3_16_539356ad9134b3.jpg","id":"539356ad9134b3","google_address":"10 Canal Street","google_city":"Bristol","google_state":"Pennsylvania","verified_zip":"19007","google_county":"Bucks County","status":"Active","add_date":"2014-06-07","circle_name":"Test Portfolio","step":"Rental","loan":"","winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins@assero24.com","fsm_phone":"2155868317","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"9","client":"Test Client","client_email":"krishna162@gmail.com","client_phone":"2157830782","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":null,"bathroom":null,"sqft":null,"lot_size":null,"list_price":"538525","built":null,"assign_date":"06/07/2014","lock_box":null,"gate_code":null,"key_code":null,"property_type":"Unknown","description":null,"sub_status":null,"occupancy_status":null,"street_view":"uploads/2015/06/25/4036/0470e4cd-ce9d-4439-8031-6be5101cd09c.JPG","marketing_front":"uploads/2015/06/25/4036/b099a190-f354-454a-8479-bec67bc41988.JPG","followed":"1"}
{"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","zip":"19007","county":"Bucks County","apt_no":"","latitude":"40.1012666","longitude":"-74.855304","profile_picture":"uploads/thumbnails/2014/06/07/16/1402165202_3_16_539356ad9134b3.jpg","id":"539356ad9134b3","google_address":"10 Canal Street","google_city":"Bristol","google_state":"Pennsylvania","verified_zip":"19007","google_county":"Bucks County","status":"Active","add_date":"2014-06-07","circle_name":"Test Portfolio","step":"Rental","loan":"","winterized":null,"boiler":null,"sump_pump":null,"septic":null,"police_id":null,"police":null,"police_phone":null,"electric_id":null,"electric":null,"electric_phone":null,"sewer_id":null,"sewer":null,"sewer_phone":null,"water_id":null,"water":null,"water_phone":null,"fsm_company_id":"5","fsm_company":"Assero Services LLC - FSM","fsm_email":"leemertins@assero24.com","fsm_phone":"2155868317","hoa_id":null,"hoa":null,"hoa_email":null,"hoa_phone":null,"client_id":"9","client":"Test Client","client_email":"krishna162@gmail.com","client_phone":"2157830782","broker_contact_id":null,"broker":null,"broker_email":null,"broker_phone":null,"lawn_contractor":null,"cleaning_contractor":null,"bedroom":null,"bathroom":null,"sqft":null,"lot_size":null,"list_price":"538525","built":null,"assign_date":"06/07/2014","lock_box":null,"gate_code":null,"key_code":null,"property_type":"Unknown","description":null,"sub_status":null,"occupancy_status":null,"street_view":"uploads/2015/06/25/4036/0470e4cd-ce9d-4439-8031-6be5101cd09c.JPG","marketing_front":"uploads/2015/06/25/4036/b099a190-f354-454a-8479-bec67bc41988.JPG"}

注意区别在于json字符串末尾的后面的项。

从 GSON 文档中它说: “在反序列化时,JSON 中缺少条目会导致将对象中的相应字段设置为 null。”

有没有办法覆盖它而不自动将其设置为 null,而只是跳过该字段?

这是我用来反序列化我的 json 的一些代码:

PropertyObject prop = visnetawrap.gsonClient.fromJson(properties.get(i).toString(), PropertyObject.class);

visnetawrap.gsonClient = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class) || f.getDeclaredClass().equals(Drawable.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            })
            .registerTypeAdapter(Date.class, new GsonDateDeserializer())
            .registerTypeAdapter(Double.class, new TypeAdapter<Double>() {
                @Override
                public void write(JsonWriter out, Double value) throws IOException {
                    if (value == null) {
                        out.nullValue();
                        return;
                    }
                    out.value(value);
                }

                @Override
                public Double read(JsonReader in) throws IOException {
                    if (in.peek() == JsonToken.NULL) {
                        in.nextNull();
                        return null;
                    }
                    String stringValue = in.nextString();
                    try {
                        return Double.valueOf(stringValue);
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            })
            .create();

【问题讨论】:

    标签: android gson realm


    【解决方案1】:

    这是我正在做的工作:

    .registerTypeAdapter(PropertyObject.class, new JsonDeserializer<PropertyObject>() {
                    @Override
                    public PropertyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                        PropertyObject prop = new PropertyObject();
                        JsonObject propObj = json.getAsJsonObject();
    
                        if (propObj.get("id") == null) {
                            return null;
                        }
    
                        prop.setPropertyId(propObj.get("id").getAsString());
    
                        if (propObj.get("followed") == null) {
                            Realm realmThread = Realm.getDefaultInstance();
    
                            PropertyObject existingProp = realmThread.where(PropertyObject.class).equalTo("propertyId", propObj.get("id").getAsString()).findFirst();
                            if (existingProp == null) {
                                prop.setPropertyFollowed(0);
                            }
                            else {
                                prop.setPropertyFollowed(existingProp.getPropertyFollowed());
                            }
    
                            realmThread.close();
                        }
                        else {
                            prop.setPropertyFollowed(propObj.get("followed").getAsInt());
                        }
    
                        return prop;
                    }
                })
    

    【讨论】:

      【解决方案2】:

      您可以创建自己的TypeAdapter

      public class YourTypeAdapter extends TypeAdapter<PropertyObject> {
      
        @Override
        public PropertyObject read(final JsonReader in) throws IOException {
          final PropertyObject obj = new PropertyObject(); //I don't know how is your obj 
      
          in.beginObject();
          boolean hasFollowedField = false;
          while (in.hasNext()) {
      
            switch (in.nextName()) {
            case "gate_code": 
              //set value to your obj
              obj.setValue(in.nextString())
              break;
              //do same thing to others...
              //...
            case "followed":
              hasFollowedField = true;
              //set value to obj
              break;
            }
            if (!hasFollowedField) {
              //set followed value to obj what you want
            }
          }
          in.endObject();
      
          return obj;
        }
      
        @Override
        public void write(final JsonWriter out, final PropertyObject obj) throws IOException {
          out.beginObject();
          out.name("gate_code").value(gate_code.getGateCode());
          //simple set name and value from obj to JsonWriter
          out.endObject();
        }
      }
      

      然后将 TypeAdapter 注册到您的 GsonBuilder obj

      希望对你有帮助

      【讨论】:

      • 让我试一试,告诉你它是如何工作的,我需要做每个名字还是只做后面的?
      • 妈的,我有很多哈哈。我明天有机会试试,会回来的。
      • 这在我的情况下不起作用。问题是从服务器获取时,JSON 字符串 1 与 JSON 字符串 2 具有相同的属性。因此,当它缺少该字段时,它会设置值,但在更新旧对象时会覆盖旧值。我正在使用 Realm 创建或更新。
      • 你需要合并 JSON obj 一和 JSON obj 二吗??
      • 是的,但如果followed为null,我不想覆盖它,因为那里可能有一个值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 2023-03-18
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多