Gson сериализация в зависимост от стойността на полето

Имам POJO, който е подобен на:

public class MyGsonPojo {

    @Expose
    @SerializedName("value1")
    private String valueOne;

    @Expose
    @SerializedName("value2")
    private boolean valueTwo;

    @Expose
    @SerializedName("value3")
    private int valueThree;

    // Getters and other stuff here
}

Проблемът е, че този обект трябва да бъде сериализиран в json тяло за повикване към сървъра. Някои полета не са задължителни за заявката и дори ако я изпратя със стойности по подразбиране и null, API отговаря по различен начин (за съжаление промяната на API не е опция).

Така че основно трябва да изключа полета от сериализация, ако някое от тях е зададено на стойност по подразбиране. Например, ако полето valueOne е null, полученият json трябва да бъде:

{
    "value2" : true,
    "value3" : 2
}

Някаква идея как да направите това безболезнено усилие? Не бих искал да изграждам тялото на json ръчно.

Всяка помощ би била чудесна. Благодаря ви за съвета.


person Serj Lotutovici    schedule 06.06.2014    source източник


Отговори (2)


Стъпки, които трябва да следвате:

  • Преобразувайте JSON низа в Map<String,Object> с помощта на Gson#fromJson()
  • Повторете картата и премахнете записа от картата, който е null
  • Формирайте JSON низа обратно от крайната карта, като използвате Gson#toJson().

Вече публикувах примерния код в същия контекст тук:

person Braj    schedule 06.06.2014

Опция 1) Използвайте TypeAdapter, вижте приетия отговор тук:

Вариант 2) Ако използвате Jackson вместо gson е възможност, можете да анотирате/сериализирате на getters вместо на полета и поставете вашата логика за връщане на всичко, от което се нуждаете за „стойности по подразбиране“ във вашите гетери.

//won't get serialized because it's private 
private String valueOne;
...
@JsonSerialize
String getValueOne(){
   if (valueOne == null) return "true"
   else...
}

Можете също така да използвате единична анотация @JsonInclude(Include.NON_NULL) или @JsonInclude(Include.NON_EMPTY) в горната част на вашия клас, за да предотвратите сериализиране на нулеви или празни полета.

person drew moore    schedule 06.06.2014
comment
Thx, за вашия отговор. За съжаление Jackson не е опция (за много обекти за рефакторинг). И TypeAdapter може да бъде изключен, ако обектът има около 10 или дори 15 полета. - person Serj Lotutovici; 07.06.2014
comment
@SerjLotutovici Какво имаш предвид може да се изключи? - person drew moore; 07.06.2014
comment
Може да се изключи като решение. Не си представям някой, който би се опитал да напише TypeAdapter за обект с 15 полета - с много шансове да направите грешка. Но благодаря за съвета на Джаксън - ще го разгледам в следващия си проект. - person Serj Lotutovici; 07.06.2014
comment
А, да, бих се съгласил с теб, ако това е така. Бих погледнал първото решение на @Braj - person drew moore; 07.06.2014