Json Jackson JDK8数据类型和参数名称模块don';我们不能一起玩

Json Jackson JDK8数据类型和参数名称模块don';我们不能一起玩,json,jackson,java-8,jackson-modules,Json,Jackson,Java 8,Jackson Modules,在我看来,Jackson JDK8数据类型模块偶尔会忽略参数名模块,这似乎有点令人惊讶,因为两者都需要JDK8并解决与JDK8相关的特定用例 这里的问题是,在没有明确指定参数名的情况下,我无法找到使JSON反序列化工作的方法(这就是参数名模块的全部内容)。只有当试图在容器对象构造函数中传递JDK8特定类型(可选)时,它才会表现出这种行为(也就是说,正常情况下,这是有效的,我已经测试过了)。代码是用javac参数-parameters编译的 问题是-如何使其工作,以便我可以利用参数名模块(即,不需

在我看来,Jackson JDK8数据类型模块偶尔会忽略参数名模块,这似乎有点令人惊讶,因为两者都需要JDK8并解决与JDK8相关的特定用例

这里的问题是,在没有明确指定参数名的情况下,我无法找到使JSON反序列化工作的方法(这就是参数名模块的全部内容)。只有当试图在容器对象构造函数中传递JDK8特定类型(
可选
)时,它才会表现出这种行为(也就是说,正常情况下,这是有效的,我已经测试过了)。代码是用javac参数
-parameters
编译的

问题是-如何使其工作,以便我可以利用参数名模块(即,不需要在构造函数中指定annotation+值,并让它通过参数名计算出属性名)

我可能弄错了,没有看引擎盖下的代码,所以我想听听我是否遗漏了什么

让我们考虑这个简单的例子。

版本堆栈(撰写本文时的所有最新版本):

容器:

private static class SimpleTest {
    @JsonProperty private Optional<String> s1;
    @JsonProperty private Optional<String> s2;
    @JsonProperty private Map<String, String> map;

    private SimpleTest(@JsonProperty("s1") Optional<String> s1, @JsonProperty("s2") Optional<String> s2, @JsonProperty("map") Map<String, String> map) {
        this.s1 = s1;
        this.s2 = s2;
        this.map = map;
    }

    static SimpleTest of(Optional<String> s1, Optional<String> s2, Map<String, String> m) {
        return new SimpleTest(s1, s2, m);
    }
}
反序列化:

@Test
public void testSer() throws JsonProcessingException {
    SimpleTest test = SimpleTest.of(Optional.of("a"), Optional.empty(), Collections.emptyMap());
    System.out.println(JacksonUtil.getMapper().writeValueAsString(test));
}
@Test
public void testDeser() throws IOException {
    String json = "{\n" +
            "  \"s1\" : \"a\",\n" +
            "  \"map\" : { }\n" +
            "}";
    JacksonUtil.getMapper().readValue(json, SimpleTest.class);
}
使用这样的容器运行
testSer()
,可以产生:

{
  "s1" : "a",
  "s2" : null,
  "map" : { }
}
使用如下输入运行
testdesr()

{
  "s1" : "a",
  "map" : { }
}
也可以工作,并产生预期结果(
s1
有值,
s2
可选。空的
映射
为空),但仅当容器构造函数定义如上所述时。我无法在以下组合中工作:
(一)


我在这里遗漏了什么?

我认为这是由于Jackson 2.6的一个遗留问题,关于多参数构造函数的检测:虽然检测到了参数名,但如果不使用
@JsonCreator
注释来标记它,构造函数本身不会保留为候选。 这是希望在2.7中解决的问题(原本应该在2.6中解决),但目前这是必要的


如果您将
@JsonCreator
添加到构造函数并删除
@JsonProperty
注释,事情应该会按预期进行。

我在Github上的答案:

我已经测试了以下代码,测试通过了:

公共类选项测试{
@试验
public void shouldDeserialize()引发IOException{
//给定
ObjectMapper ObjectMapper=新的ObjectMapper();
registerModule(新的Jdk8Module());
registerModule(新参数NamesModule());
//什么时候
字符串json=“{\'s1\':\'a\',\'map\':{}”;
SimpleTest SimpleTest=objectMapper.readValue(json,SimpleTest.class);
然后(simpleTest).isEqualToComparingFieldByField(新simpleTest(可选的.of(“a”)、可选的.empty()、新的HashMap());
}
私有静态类SimpleTest{
私有可选s1;
私有可选s2;
私人地图;
私有SimpleTest(可选s1、可选s2、映射){
这是1.s1=s1;
这1.s2=s2;
this.map=map;
}
静态SimpleTest of(可选s1、可选s2、映射m){
返回新的SimpleTest(s1,s2,m);
}
}
}

请注意,这是针对jackson parameter name模块中的最新状态进行的测试,所有依赖项都设置为2.6.2。

请参阅其他讨论和。感谢您的回复和努力-您的方法是有效的,实际上整个问题可能是一个恶作剧/IDE,因为我发现编译中莫名其妙地缺少javac参数设置。更重要的是,反序列化不需要任何注释,它只是工作而已。我可以在我这边确认测试通过-很可能我们是在追踪幽灵,因为这似乎是一个IDE问题(编译器选项中的
-parameters
javac选项已消失)。感谢你们的帮助和时间。序列化也有效,忘了在上面的代码中包含它。:)
{
  "s1" : "a",
  "map" : { }
}
private SimpleTest(Optional<String> s1, Optional<String> s2, Map<String, String> map) {...}
private SimpleTest(@JsonProperty Optional<String> s1, @JsonProperty Optional<String> s2, @JsonProperty Map<String, String> map) {...}
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com._3esi.load.bootstrap.ScratchPad$SimpleTest]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {
  "s1" : "a",
  "map" : { }
}; line: 2, column: 3]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1106)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:294)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:131)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3731)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2724)