Я работал с GSON, и это было действительно продуктивно во всех случаях использования сериализации, но есть один случай, который меня поразил. Итак, у меня есть POJO, который я хочу сериализовать:
@JsonAdapter(ContactSerializer.class)
public class Contact{
// TODO: Make this impl. implement Parcelable
@Expose
private Long contactId;
@Expose
private String displayName;
// DO NOT INCLUDE IN JSON
private String nickName;
// DO NOT INCLUDE IN JSON
// Note: Can be included later
private String homePhone;
@Expose
private String mobilePhone;
// DO NOT INCLUDE IN JSON
// Note: Can be included later
private String workPhone;
// DO NOT INCLUDE IN JSON
// Note: Can be included later
private String photoPath;
// Combine the below two fields into 1
private String homeEmail;
// Instead we combine home email and work email under "emails" for serialization
private String workEmail;
// DO NOT INCLUDE IN JSON
// Note: Can be included later
private String companyName;
// DO NOT INCLUDE IN JSON
// Note: Can be included later
private String title;
public Contact(@NonNull Long contactId, @NonNull String displayName) {
this.contactId = contactId;
this.displayName = displayName;
}
// All fields constructor
public Contact(@NonNull Long contactId, @NonNull String displayName, String nickName, String homePhone,
String mobilePhone, String workPhone, String photoPath, String homeEmail,
String workEmail, String companyName, String title) {
this.contactId = contactId;
this.displayName = displayName;
this.nickName = nickName;
this.homePhone = homePhone;
this.mobilePhone = mobilePhone;
this.workPhone = workPhone;
this.photoPath = photoPath;
this.homeEmail = homeEmail;
this.workEmail = workEmail;
this.companyName = companyName;
this.title = title;
}
}
Теперь, как вы можете видеть из приведенного выше контакта, я хочу объединить все электронные письма в массив JSON и добавить в окончательный JSON перед отправкой его на сервер.
Для этого я решил использовать собственный сериализатор:
public class ContactSerializer implements JsonSerializer<Contact> {
private final Gson gson = new Gson();
@Override
public JsonElement serialize(Contact src, Type typeOfSrc, JsonSerializationContext context) {
JsonElement jsonElement = context.serialize(src, typeOfSrc);
List<String> emails = new ArrayList<>();
if(src.getHomeEmail() != null && !TextUtils.isEmpty(src.getHomeEmail())){
emails.add(src.getHomeEmail());
}
if(src.getWorkEmail() != null && !TextUtils.isEmpty(src.getWorkEmail())){
emails.add(src.getWorkEmail());
}
if(!emails.isEmpty()){
// Add a field for array
JsonArray emailJsonArray = new JsonArray();
for(String email : emails){
emailJsonArray.add(email);
}
jsonElement.getAsJsonObject().add("emails", emailJsonArray);
}
else{
// By default, we would like to have null values represented
jsonElement.getAsJsonObject().add("emails", null);
}
return jsonElement;
}
}
Единственная проблема в том, что она не работает как задумано - она идет в бесконечном цикле из-за вызова context.serialize(src, typeOfSrc);
Это было довольно неожиданно, особенно из библиотеки, подобной GSON. Есть ли обходной путь или инструмент для выполнения сериализации по умолчанию, а затем ее изменения?