Java 序列化:忽略一个元素包含空值的列表属性

Java 序列化:忽略一个元素包含空值的列表属性,java,serialization,morphia,playframework-2.6,Java,Serialization,Morphia,Playframework 2.6,我正在使用mongoDB开发java play framework 2.6 web应用程序。 让我们考虑这个模型结构: public class Beneficiary { private Type type; // enum: NGO, PUBLIC_ADMINISTRATION .. private Company company; } public class Company { private String name; private String

我正在使用mongoDB开发java play framework 2.6 web应用程序。 让我们考虑这个模型结构:

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;
}
我不想在数据库中存储此表单中的
agent
字段。如果元素的所有字段都是空字符串,我想完全忽略它

我尝试使用
@JsonInclude(JsonInclude.Include.NON_EMPTY)
类和/或字段进行注释,但这仅适用于
类中的字段
类型

有没有一种不用编写自定义注释的方法可以做到这一点


谢谢

您正在使用哪个JSON序列化库?杰克逊还是格森

两者都支持定义自己的自定义序列化程序

您可以为Person类型定义一个序列化程序,然后它将在遇到Person数据时调用您的代码来序列化JSON,如果所有字段都为空,您可以忽略

为杰克逊

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();
    }

还有更多选项,但我会编写一些代码来检查这些字段是否为空字符串,如果是,则将“代理”设置为null

所以,假设你有这样的东西:

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": ""
}
]

另一个选项是在播放中设置,以便当用户在表单中输入空字符串时,接收空字符串而不是“”。尽管最终仍然会有一个所有字段都设置为null的代理

使用Morphia提供的@PreSave注释,如下所示

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");
        }
        ....
    }
}
公共类受益人{
私有类型类型;//枚举:NGO,公共管理。。
私营公司;
} 
公营公司{
私有字符串名称;
私有字符串注册号;
私人名单代理;
@预示
公共无效预存(BSONObject dbObj){
列表代理=(List)dbObj.get(“代理”);
对于(int i=0;i
感谢您的回答@VladDinulescu。我将用编辑命题更新问题
"agent": [
{
    "name": "",
    "email": "",
    "phoneNumber": ""
}
]
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");
        }
        ....
    }
}