我正在使用@JsonUnwrapped属性进行反序列化。只要我不添加自定义模块,它就可以正常工作。后反序列化注释需要该模块(以便我可以在反序列化完成后标记要执行的方法)。
当我添加模块时 - 我收到反序列化错误 - 无法识别的字段。
请提出问题所在。
错误
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "test-name" (class dgt.common.core.configuration.extension.Person), not marked as ignorable (4 known properties: "name", "aName"])
at [Source: (String)"{"test-name":"xx"}"; line: 1, column: 15] (through reference chain: dgt.common.core.configuration.extension.Person["test-name"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:855)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1212)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1604)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1582)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:299)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)
at com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer.deserialize(DelegatingDeserializer.java:95)
at dgt.common.core.configuration.extension.PostDeserializeImpl.deserialize(JacksonUnwrappedTest.java:96)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3402)
at dgt.common.core.configuration.extension.JacksonUnwrappedTest.test(JacksonUnwrappedTest.java:145)
这是一个代码:
POJO:
class Name extends Configuration {
@JsonProperty("test-name")
private String aName;
public String getName() {
return aName;
}
public void setName(String name) {
aName = name;
}
}
class Person extends Configuration {
@JsonUnwrapped
private Name aName;
public Name getName() {
return aName;
}
public void setName(Name name) {
aName = name;
}
}
自定义解串器:
class PostDeserializeImpl extends DelegatingDeserializer {
private final BeanDescription beanDescription;
public PostDeserializeImpl(JsonDeserializer<?> delegate, BeanDescription beanDescription) {
super(delegate);
this.beanDescription = beanDescription;
}
@Override
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
return new JsonPostDeserializeImpl(newDelegatee, beanDescription);
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Object deserializedObject = super.deserialize(p, ctxt);
callPostDeserializeMethods(deserializedObject);
return deserializedObject;
}
private void callPostDeserializeMethods(Object deserializedObject) {
for (AnnotatedMethod method : beanDescription.getClassInfo()
.memberMethods()) {
if (method.hasAnnotation(JsonPostDeserialize.class)) {
try {
method.callOn(deserializedObject);
} catch (Exception e) {
throw new RuntimeException("Failed to call @JsonPostDeserialize annotated method in class "
+ beanDescription.getClassInfo()
.getName(), e);
}
}
}
}
}
测试:
public class JacksonUnwrappedTest {
private static ObjectMapper getMapper() {
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDescription,
JsonDeserializer<?> originalDeserializer) {
return new PostDeserializeImpl(originalDeserializer, beanDescription);
}
});
return new ObjectMapper().registerModules(module);
}
@Test
public void test() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Name name = new Name();
name.setName("xx");
name.setSurname("yy");
Person person = new Person();
person.setName(name);
person.setAge("23");
String string = person.toJsonString();
System.out.println(string);
Person p = getMapper().readValue(string, Person.class);
System.out.println(p);
}
}