简体   繁体   English

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

[英]Serialization: ignore list property with one element that contains empty values

I'm working on a java play framework 2.6 web application with mongoDB.我正在使用 mongoDB 开发一个 java play framework 2.6 web 应用程序。 Let's consider this model structure:让我们考虑这个模型结构:

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

I receive this data from a form:我从表单中收到此数据:

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

I don't want to store in the database the field agent in this form.我不想以这种形式将现场agent存储在数据库中。 I want to ignore it completely if all the fields of the element are empty strings.如果元素的所有字段都是空字符串,我想完全忽略它。

I tried annotating with @JsonInclude(JsonInclude.Include.NON_EMPTY) classes and/or fields but this only worked for the field type in the Beneficiary class.我尝试使用@JsonInclude(JsonInclude.Include.NON_EMPTY)类和/或字段进行注释,但这仅适用于Beneficiary类中的字段type

Is there a way to do this without writing a custom annotation?有没有办法在不编写自定义注释的情况下做到这一点?

Thanks谢谢

Which JSON serialization library are you using?您使用的是哪个 JSON 序列化库? Jackson or Gson?杰克逊还是格森?

Both have support to define your own custom serializers.两者都支持定义您自己的自定义序列化程序。

You can define a serializer for type Person, and then it will call your code to serialize the JSON when it encounters Person data, you can ignore if all the fields are empty.您可以为 Person 类型定义一个序列化器,然后它会在遇到 Person 数据时调用您的代码来序列化 JSON,如果所有字段都为空,您可以忽略。

For Jackson对于杰克逊

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

} }

And on your Person class, add this annotation在你的 Person 类上,添加这个注释

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

There are more options, but I would write some code that checks if those fields are empty strings, and, if so, sets the "agent" to null.还有更多选项,但我会编写一些代码来检查这些字段是否为空字符串,如果是,则将“代理”设置为 null。

So, assuming you have something like:所以,假设你有类似的东西:

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 you have many similar cases, you can also write some code that does this through reflection.如果你有很多类似的情况,你也可以写一些代码通过反射来做到这一点。

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

By the way, the data that you should receive from the form should be a bit different,顺便说一句,你应该从表单接收的数据应该有点不同,

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

Another options is to set in Play so that when the user enters an empty string in the form, to receive NULL string instead of "".另一个选项是在 Play 中设置,以便当用户在表单中输入空字符串时,接收 NULL 字符串而不是“”。 Although you'll still end up with an Agent with all fields set to null.尽管您最终仍会得到一个所有字段都设置为 null 的 Agent。

Used @PreSave annotation provided by Morphia like this像这样使用 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");
        }
        ....
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM