序列化:忽略列表 属性 其中一个元素包含空值
Serialization: ignore list property with one element that contains empty values
我正在使用 mongoDB 开发 java play framework 2.6 网络应用程序。
让我们考虑一下这个模型结构:
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)
classes and/or 字段进行注释,但这仅适用于 Beneficiary
class 中的字段 type
.
有没有办法不用写自定义注释就可以做到这一点?
谢谢
您使用哪个 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();
}
}
然后在您的个人 class 上添加此注释
@JsonSerialize(using = PersonSerializer.class)
Person {
.....
}
还有更多选项,但我会编写一些代码来检查这些字段是否为空字符串,如果是,则将 "agent" 设置为 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": ""
}
]
另一个选项是在 Play 中设置,当用户在表单中输入空字符串时,接收 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");
}
....
}
}
我正在使用 mongoDB 开发 java play framework 2.6 网络应用程序。 让我们考虑一下这个模型结构:
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)
classes and/or 字段进行注释,但这仅适用于 Beneficiary
class 中的字段 type
.
有没有办法不用写自定义注释就可以做到这一点?
谢谢
您使用哪个 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();
}
}
然后在您的个人 class 上添加此注释
@JsonSerialize(using = PersonSerializer.class)
Person {
.....
}
还有更多选项,但我会编写一些代码来检查这些字段是否为空字符串,如果是,则将 "agent" 设置为 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": ""
}
]
另一个选项是在 Play 中设置,当用户在表单中输入空字符串时,接收 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");
}
....
}
}