具有单个参数的Jackson单个参数构造函数与ParameterNameModule失败

时间:2016-12-20 13:33:42

标签: java json java-8 jackson

我正在使用带有ParameterNamesModule的Jackson 2.8.5 for Java 8(https://github.com/FasterXML/jackson-modules-java8)。

当我想使用单个参数对单个构造函数反序列化类时,我的问题对于一个用例非常具体。这是一个重现行为的测试:

public class JacksonTest {

    @Test
    public void TestReadValue() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper()
                .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
                .setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.PUBLIC_ONLY)
                .registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));

        ImmutableIdentity identity = objectMapper.readValue("{\"id\":\"ABCDEF\"}", ImmutableIdentity.class);

        assertEquals("ABCDEF", identity.id);
    }

    private static final class ImmutableIdentity {

        private final String id;

        public ImmutableIdentity(final String id) {
            Objects.requireNonNull(id, "The id must not be null.");

            this.id = id;
        }
    }

}

测试失败的原因是:

  

com.fasterxml.jackson.databind.JsonMappingException:无法构造   JacksonTest的实例$ ImmutableIdentity,问题:id不能是   空值。在[来源:{" id":" ABCDEF"}; line:1,column:15]

有趣的是,如果我在构造函数中添加另一个参数,那么测试就会通过。

public class JacksonTest {

    @Test
    public void TestReadValue() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper()
                .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
                .setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.PUBLIC_ONLY)
                .registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));

        ImmutableIdentity identity = objectMapper.readValue("{\"id\":\"ABCDEF\"}", ImmutableIdentity.class);

        assertEquals("ABCDEF", identity.id);
    }

    private static final class ImmutableIdentity {

        private final String id;

        public ImmutableIdentity(final String id, **final String unused**) {
            Objects.requireNonNull(id, "The id must not be null.");

            this.id = id;
        }
    }

}

我真的不喜欢在构造函数中使用无用的参数来使其不那么模糊,因为它在我的业务对象中没有任何价值,特别是它们是例如ProjectId,或者是一些抽象的Id定义我的实体,我也需要手动构建它们。所以我想找到一个杰克逊的配置来支持这个,但我不能。

我也在这里为维护者转发:https://github.com/FasterXML/jackson-modules-java8/issues/8

1 个答案:

答案 0 :(得分:2)

您是否有机会使用JacksonTest选项编译-parameters?如果是这样,这是预期的行为。 单个参数构造函数在历史上被用作委托创建者。 即使我们创建了模块,我也与@staxman讨论过这个问题。各种用户多次出现此问题,有关详细信息,请参阅this issue。 展望未来,希望在3.0中进行更改,有关详细信息,请参阅this topic

更新:关于3.0更改,请参阅this issue。如果您希望更改此行为,请添加+1或评论。目前还不清楚这两种方法是否更好,因为有些用户需要旧的行为(有关详细信息,请参阅问题)。