Сериализация: игнорировать свойство списка с одним элементом, который содержит пустые значения - PullRequest
0 голосов
/ 01 ноября 2018

Я работаю над веб-приложением java play framework 2.6 с mongoDB. Давайте рассмотрим эту модель структуры:

public class Beneficiary {  
    private Type type; // enum: NGO, PUBLIC_ADMINISTRATION ..
    private Company company;
} 
public class Company {
    private String name;
    private String registrationNumber;
    private List<Person> agent;
}
public class Person {
    private String name;
    private String email;
    private String phoneNumber;
}

Я получаю эти данные из формы:

{
  "type" : "NGO",
  "company" : {
    "name" : "ngo name",
    "registrationNumber" : "2233",
    "agent" : [
      {
        "name" : "",
        "email" : "",
        "phoneNumber" : ""
      }
    ]
  }
}

Я не хочу хранить в базе данных поле agent в этой форме. Я хочу полностью игнорировать это, если все поля элемента являются пустыми строками.

Я пытался комментировать с @JsonInclude(JsonInclude.Include.NON_EMPTY) классами и / или полями, но это работало только для поля type в Beneficiary классе.

Есть ли способ сделать это без написания пользовательской аннотации?

Спасибо

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

Есть и другие опции, но я бы написал некоторый код, который проверяет, являются ли эти поля пустыми строками, и, если это так, устанавливает "агент" в ноль.

Итак, если у вас есть что-то вроде:

saveCompany(Company company) {
   agent=company.getAgent();
   if (StringUtils.isEmpty(agent.getName()) && StringUtils.isEmpty(agent.getEmail()) && StringUtils.isEmpty(agent.getPhoneNumber)) {
        company.setAgent(null);
   }

   saveToMongo(company);
}

Если у вас много похожих случаев, вы также можете написать некоторый код, который делает это путем отражения.

if (allFieldsAreEmpty(company.getAgent())) {
       company.setAgent(null);
}

Кстати, данные, которые вы должны получить из формы, должны немного отличаться,

"agent": [
{
    "name": "",
    "email": "",
    "phoneNumber": ""
}
]

Другой вариант - установить в Play так, чтобы, когда пользователь вводит пустую строку в форму, он получал NULL-строку вместо "". Хотя вы все равно получите агента со всеми полями, равными нулю.

0 голосов
/ 06 ноября 2018

Используется аннотация @PreSave, предоставленная Morphia, вот так

public class Beneficiary {  
    private Type type; // enum: NGO, PUBLIC_ADMINISTRATION ..
    private Company company;
} 
public class Company {
    private String name;
    private String registrationNumber;
    private List<Person> agent;

    @PreSave
    public void preSave(BSONObject dbObj) {
        List<?> agents = (List<?>) dbObj.get("agents");
        for (int i = 0; i < agents.size(); i++) {
            if (Json.toJson(agents.get(i)).size() == 0) {
                agents.remove(i);
            }
        }

        if (agents.size() == 0) {
            dbObj.removeField("agents");
        }
        ....
    }
}
public class Person {
    private String name;
    private String email;
    private String phoneNumber;

    @PreSave
    public void preSave(BSONObject dbObj) {
        if (dbObj.get("name") != null && dbObj.get("name").equals("")) {
            dbObj.removeField("name");
        }
        ....
    }
}
0 голосов
/ 01 ноября 2018

Какую библиотеку JSON-сериализации вы используете? Джексон или Гсон?

Оба имеют поддержку для определения ваших собственных сериализаторов.

Вы можете определить сериализатор для типа Person, а затем он вызовет ваш код для сериализации JSON, когда он встретит данные Person, вы можете игнорировать, если все поля пусты.

Для Джексона

public class PersonSerializer extends StdSerializer<Person> {

    public PersonoSerializer() {
        this(null);
    }

    public PersonSerializer(Class<Person> t) {
        super(t);
    }

    @Override
    public void serialize(
      Item value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException {
        if(value.name.isEmpty() && value.email.isEmpty() && value.phoneNumber.isEmpty()) return;

        jgen.writeStartObject();
        jgen.writeNumberField("id", value.id);
        jgen.writeStringField("itemName", value.itemName);
        jgen.writeNumberField("owner", value.owner.id);
        jgen.writeEndObject();
    }

}

А в свой класс Person добавьте эту аннотацию

@JsonSerialize(using = PersonSerializer.class)
Person {
.....
}
...