Android GSON忽略JSON字符串中缺少的值

Android GSON忽略JSON字符串中缺少的值,android,gson,realm,Android,Gson,Realm,我正在android应用程序中使用GSON。目前,我正在设置一个包含JSON字符串中名为“followed”的值的方法。JSON字符串中的一个项目包含以下内容,而第二个字符串不包含以下内容。我使用Realm来持久化唯一的对象,这样您就可以看到它被覆盖了 以下是两个要比较的json字符串作为示例: {"customer_case":"OFFICE001","circle_id":"3","address":"10 Canal St","city":"Bristol","state":"PA","z

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

以下是两个要比较的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();
PropertyObject prop=visnetawap.gsonClient.fromJson(properties.get(i).toString(),PropertyObject.class);
visnetawrap.gsonClient=new GsonBuilder()
.SetExclutionStrategy(新的ExclutionStrategy)(){
@凌驾
公共布尔值shouldSkipField(字段属性f){
返回f.getDeclaringClass().equals(RealmObject.class)| f.getDeclaredClass().equals(Drawable.class);
}
@凌驾
公共布尔shouldSkipClass(类clazz){
返回false;
}
})
.registerTypeAdapter(Date.class,新的GsonDateDeserializer())
.registerTypeAdapter(Double.class,新类型适配器(){
@凌驾
public void write(JsonWriter out,双值)抛出IOException{
如果(值==null){
out.nullValue();
返回;
}
out.值(value);
}
@凌驾
公共双读(JsonReader in)引发IOException{
if(in.peek()==JsonToken.NULL){
in.nextNull();
返回null;
}
String stringValue=in.nextString();
试一试{
返回Double.valueOf(stringValue);
}捕获(数字格式){
返回null;
}
}
})
.create();
您可以创建自己的

public类YourTypeAdapter扩展了TypeAdapter{
@凌驾
公共属性对象读取(中的最终JsonReader)引发IOException{
final PropertyObject obj=新的PropertyObject();//我不知道你的obj怎么样
in.beginObject();
布尔hasFollowedField=false;
while(在.hasNext()中){
开关(在.nextName()中){
案例“门代码”:
//将值设置为您的obj
obj.setValue(在.nextString()中)
打破
//对别人做同样的事。。。
//...
“随后”一案:
hasFollowedField=true;
//将值设置为obj
打破
}
如果(!hasFollowedField){
//将跟随值设置为您想要的对象
}
}
in.endObject();
返回obj;
}
@凌驾
public void write(最终JsonWriter out,最终PropertyObject obj)抛出IOException{
out.beginObject();
out.name(“gate_code”).value(gate_code.getGateCode());
//从obj到JsonWriter的简单集合名称和值
out.endObject();
}
}
然后将TypeAdapter注册到GsonBuilder obj


希望它能有所帮助

以下是我作为一个工作环境所做的工作:

.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;
                }
            })
.registerTypeAdapter(PropertyObject.class,新的JsonDeserializer()){
@凌驾
公共属性对象反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
PropertyObject prop=新的PropertyObject();
JsonObject propObj=json.getAsJsonObject();
if(propObj.get(“id”)==null){
返回null;
}
prop.setPropertyId(propObj.get(“id”).getAsString());
if(propObj.get(“followered”)==null){
Realm realmThread=Realm.getDefaultInstance();
PropertyObject existingProp=realmThread.where(PropertyObject.class).equalTo(“propertyId”,propObj.get(“id”).getAsString()).findFirst();
if(existingProp==null){
属性SetPropertyFollowing(0);
}
否则{
prop.setPropertyFollowed(existingProp.getPropertyFollowed());
}
realmThread.close();
}
否则{
prop.setPropertyFollowed(propObj.get(“followed”).getAsInt());
}
返回道具;
}
})

让我试试,让你知道它是如何工作的,我需要做每一个名字,还是只是跟着做?该死,我有很多哈哈。我明天会有机会尝试,会回来的。这在我的情况下不起作用。问题是,从服务器抓取时,JSON字符串1与JSON字符串2具有相同的属性。因此,当缺少字段时,它会设置值,但在更新旧对象时会覆盖旧值。我正在使用Realm创建或更新。您需要合并JSON obj one和JSON obj two??是的,但如果后跟为null,我不想覆盖它,因为那里可能有一个值。
.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;
                }
            })