【问题标题】:Jackson single argument constructor with single argument fails with ParameterNameModule带有单个参数的杰克逊单参数构造函数因 ParameterNameModule 而失败
【发布时间】:2017-05-05 17:53:29
【问题描述】:

我正在使用 Jackson 2.8.5 和 ParameterNamesModule 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”};行:1,列: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实体,我也需要手动构建它们。所以我想找一个Jackson的配置来支持这个,但我做不到。

我还在这里为维护者交叉发布:https://github.com/FasterXML/jackson-modules-java8/issues/8

【问题讨论】:

    标签: java json java-8 jackson


    【解决方案1】:

    您是否有机会使用-parameters 选项编译JacksonTest?如果是这样,这是预期的行为。 单参数构造函数在历史上被用作委托创建者。 即使在我们创建模块时,我也与@staxman 讨论过这个问题。不同用户多次弹出该问题,详情请参阅this issue。 展望未来,这有望在 3.0 中有所改变,详情请参阅this topic

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

    【讨论】:

    • 好吧,你的意思是单参数构造函数由于遗留行为而模棱两可?我现在明白了,感谢您提供这些讨论的答案和链接。
    • 如果有人正在寻找修复/解决方法:“如果类 Person 具有单个参数构造函数,则其参数需要使用 @JsonProperty("propertyName") 进行注释”来源:github.com/FasterXML/jackson-modules-java8/blob/master/…
    • @JsonCreator注释构造函数就足够了。你不应该需要@JsonProperty
    猜你喜欢
    • 1970-01-01
    • 2020-10-19
    • 2015-01-23
    • 2016-12-31
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    相关资源
    最近更新 更多