我正在使用 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: Can not construct instance of JacksonTest$ImmutableIdentity, problem: The id must not be null. at [Source: {"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;
}
}
}
我真的不喜欢在这里的构造函数中使用无用参数来减少歧义的想法,因为它在我的业务对象中没有值(value),尤其是它们是例如 ProjectId 或定义我的一些抽象 Id实体,我也需要手动构建它们。所以我想找到一个 Jackson 的配置来支持这个,但我找不到。
我还在此处交叉发布给维护者:https://github.com/FasterXML/jackson-modules-java8/issues/8
最佳答案
您是否有机会使用 -parameters
选项编译 JacksonTest
?如果是这样,这是预期的行为。
单参数构造函数在历史上被用作委托(delegate)创建者。
即使在我们创建模块时,我也曾与@staxman 讨论过这个问题。各种用户多次弹出此问题,请参阅 this issue了解详情。
展望 future ,这有望在 3.0 中得到改变,请参阅 this topic了解详情。
更新:关于 3.0 更改,请参阅 this issue .如果您希望更改此行为,请添加 +1 或发表评论。目前尚不清楚这两种方法是否更好,因为有些用户需要旧的行为(有关更多详细信息,请参阅问题)。
关于java - 具有单个参数的 Jackson 单参数构造函数因 ParameterNameModule 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41243608/