在我看來,傑克遜JDK8數據類型模塊偶爾會忽略參數名稱模塊,這似乎有點令人驚訝,因爲它們都需要JDK8並解決具體使用情況到JDK8。傑克遜JDK8數據類型和參數名稱模塊不能一起玩
這裏的問題是我找不到一個方法來使JSON反序列化工作沒有明確指定參數名稱(這是參數名稱模塊應該是什麼)。只有當試圖在容器對象構造函數中傳遞特定於JDK8的類型(Optional<T>
)時(即,通常,這可以工作,並且我已經測試過),它也表現出這種行爲。該代碼使用javac參數-parameters
進行編譯。
問題是 - 如何使它工作,以便我可以利用參數名稱模塊(即不需要在構造函數中指定註釋+值,並讓它通過參數名稱找出屬性名稱)?
我可能被誤認爲沒有看過引擎蓋下的代碼,所以我想聽聽是否有一些我錯過了。
讓我們考慮這個簡單的例子。
版本堆棧(所有最新版本撰寫本文時):
private val jacksonVer = "2.6.1"
private val jacksonCore: ModuleID = "com.fasterxml.jackson.core" % "jackson-core" % jacksonVer withSources() withJavadoc()
private val jacksonDataBind: ModuleID = "com.fasterxml.jackson.core" % "jackson-databind" % jacksonVer withSources() withJavadoc()
private val jacksonAnnotations: ModuleID = "com.fasterxml.jackson.core" % "jackson-annotations" % jacksonVer withSources() withJavadoc()
private val jacksonParamNames: ModuleID = "com.fasterxml.jackson.module" % "jackson-module-parameter-names" % "2.6.2" withSources() withJavadoc()
private val jacksonJdk8DataType: ModuleID = "com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % "2.4.3" withSources() withJavadoc()
集裝箱:
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" : { }
}
運行testDeser()
與輸入諸如此
{
"s1" : "a",
"map" : { }
}
也適用,併產生預期的結果(s1
具有價值,s2
是Optional.empty
和map
是空),但前提是容器構造函數的定義如上。我不把它在下列組合工作:
1)
private SimpleTest(Optional<String> s1, Optional<String> s2, Map<String, String> map) {...}
2)
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)
我在這裏錯過了什麼?
查看其他討論[here](https://github.com/FasterXML/jackson-module-parameter-names/issues/26)和[here](https://github.com/FasterXML/jackson-datatype -jdk8 /問題/ 16)。 – quantum