我正在执行UPDATE操作,以便将传入POJO中设置的所有non-null
属性都复制到另一个对象(相同类型)中,并且嵌套属性也会发生这种情况。
例如:
POJO:
public class Person {
private String homePhoneNumber;
private String officePhoneNumber;
private Address address;
public String getHomePhoneNumber() {
return homePhoneNumber;
}
// getter/setters
}
public class Address {
private String street;
private String houseNumber;
public String getStreet() {
return street;
}
// getter/setters
}
// Source
Person sourcePerson = new Person();
sourcePerson.setHomePhone("123");
Address address1 = new Address();
address1.setStreet("Street");
sourcePerson.setAddress(address1);
//Dest person
Person destPerson = new Person();
destPerson.setOfficePhone("456");
destPerson.setHomePhone("123");
Address address2 = new Address();
address2.setStreet("Street2");
address2.setHouseNumber("246");
destPerson.setAddress(address2);
ObjectMapper mapper = new ObjectMapper();
//skip setters for null values
mapper.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SKIP));
Person result = mapper.updateValue(destPerson, sourcePerson);
因此,我想复制non-null
中设置的所有sourcePerson
属性,以复制到destPerson
中,即覆盖仅destperson
的那些属性, sourcePerson
已设置,其他属性保持不变。
使用
Person result = mapper.updateValue(destPerson, sourcePerson);
对嵌套属性不起作用。它正在从源到目的地替换整个Address
对象
我搜索了杰克逊(Jackson),找到了杰克逊(Jackson)的merge
功能:
mapper.setDefaultMergeable(true);
但是,添加此配置会使null
中的sourcePerson
值也使destPerson
中的值也无效,这似乎很奇怪。
mapper.configOverride(Address.class).setMergeable(true);
以上配置适用于我想要的。但是我有很多POJO嵌套资源,所以我不希望每个POJO都有特定的配置。
使用jackson
可以做到这一点吗?
答案 0 :(得分:0)
您可以首先启用关于合并
的错误报告com.fasterxml.jackson.databind.MapperFeature#IGNORE_MERGE_FOR_UNMERGEABLE
这必须是错误的。
mapper.configOverride()
确实很奇怪,但mapper.setDefaultMergeable()
却不是。
在您的示例中我看不到二传手。您是否有机会在Person类中使用@JsonSetter注释?然后它们将覆盖映射器配置。
在 jackson-databind 单元测试中,我看到它们使用的是mapper.readerForUpdating()
而不是mapper.updateValue
:
private final ObjectMapper MAPPER = objectMapperBuilder()
// 26-Oct-2016, tatu: Make sure we'll report merge problems by default
.disable(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)
.build();
public void testBeanMergingWithNullDefault() throws Exception
{
// By default `null` should simply overwrite value
ConfigDefault config = MAPPER.readerForUpdating(new ConfigDefault(5, 7))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config);
assertNull(config.loc);
// but it should be possible to override setting to, say, skip
// First: via specific type override
// important! We'll specify for value type to be merged
ObjectMapper mapper = newObjectMapper();
mapper.configOverride(AB.class)
.setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SKIP));
config = mapper.readerForUpdating(new ConfigDefault(137, -3))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config.loc);
assertEquals(137, config.loc.a);
assertEquals(-3, config.loc.b);
// Second: by global defaults
mapper = newObjectMapper();
mapper.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.SKIP));
config = mapper.readerForUpdating(new ConfigDefault(12, 34))
.readValue(aposToQuotes("{'loc':null}"));
assertNotNull(config.loc);
assertEquals(12, config.loc.a);
assertEquals(34, config.loc.b);
}
还值得尝试直接在com.fasterxml.jackson.annotation.JsonMerge
类中使用Person
。