1

我正在使用@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);
    }
}
4

0 回答 0