2016-09-08 61 views
13

我在結合傑克遜和龍目島進行實驗。這些都是我的課:不能讓傑克遜和龍目一起工作

package testelombok; 

import com.fasterxml.jackson.annotation.JsonCreator; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import lombok.AllArgsConstructor; 
import lombok.Value; 
import lombok.experimental.Wither; 

@Value 
@Wither 
@AllArgsConstructor([email protected]__(@JsonCreator)) 
public class TestFoo { 
    @JsonProperty("xoom") 
    private String x; 
    private int z; 
} 
package testelombok; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.xebia.jacksonlombok.JacksonLombokAnnotationIntrospector; 
import java.io.IOException; 

public class TestLombok { 

    public static void main(String[] args) throws IOException { 
     TestFoo tf = new TestFoo("a", 5); 
     System.out.println(tf.withX("b")); 
     ObjectMapper om = new ObjectMapper().setAnnotationIntrospector(new JacksonLombokAnnotationIntrospector()); 
     System.out.println(om.writeValueAsString(tf)); 
     TestFoo tf2 = om.readValue(om.writeValueAsString(tf), TestFoo.class); 
     System.out.println(tf2); 
    } 

} 

這些都是我加入到CLASSPTH JAR文件:

我使用Netbeans編譯它(我不認爲這真的是相關的,但我這個報告無論如何,使其完美和忠實可再現)。上述五個JAR保存在項目文件夾內的「lib」文件夾中(以及「src」,「nbproject」,「test」和「build」)。我通過項目屬性中的「添加JAR /文件夾」按鈕將它們添加到Netbeans中,並按照上面列表中的順序列出它們。該項目是一個標準的「Java應用程序」類型的項目。

此外,NetBeans項目配置爲 「不要在保存時編譯」, 「生成調試信息」, 「報告已棄用的API」, 「跟蹤Java的依賴」,「activacte註解在編輯器中激活「和」激活註解處理「。 Netbeans中沒有明確配置註釋處理器或註釋處理選項。另外,在編譯器命令行中傳遞「-Xlint:all」命令行選項,編譯器在外部VM上運行。

我的javac版本是1.8.0_72,我的java版本是1.8.0_72-b15。我的Netbeans是8.1。

我的項目編譯得很好。但是,它在執行中會引發異常。這個例外似乎不是任何看起來很容易或明顯可修復的東西。下面是輸出,包括堆棧跟蹤:

TestFoo(x=b, z=5) 
{"z":5,"xoom":"a"} 
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for testelombok.TestFoo, annotations: {interface [email protected]es(value=[x, z]), interface [email protected]son.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator 
at [Source: {"z":5,"xoom":"a"}; line: 1, column: 1] 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:296) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142) 
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:475) 
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3890) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3785) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833) 
    at testelombok.TestLombok.main(TestLombok.java:14) 
Caused by: java.lang.IllegalArgumentException: Argument #0 of constructor [constructor for testelombok.TestFoo, annotations: {interface [email protected]es(value=[x, z]), interface [email protected]son.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator 
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerConstructors(BasicDeserializerFactory.java:511) 
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:323) 
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:253) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:219) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:141) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352) 
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264) 
    ... 7 more 

我已經試了一下隨機與@Value@AllArgsConstructor註釋戳,但我不能讓任何好轉。

我googled例外和found an old bug report on jacksonanother one that is open, but seems to be related to something else。但是,這仍然沒有說明什麼是這個錯誤或如何解決它。另外,我找不到其他地方有用的東西。

因爲我想要做的是龍目和傑克遜的非常基本的用法,似乎很奇怪,我找不到有關如何解決此問題的更多有用信息。也許我錯過了什麼?

除了只是說「不使用龍目島」或「不使用傑克遜」,做任何人有任何關於如何解決這個任何想法?

回答

1

如果您使用它的"mixin" pattern,您可以讓傑克遜幾乎玩任何東西。基本上,它可以讓您將傑克遜註釋添加到現有類中,而無需實際修改該類。我傾向於在這裏推薦它,而不是一個龍目島解決方案,因爲這解決了傑克遜與傑克遜功能有關的問題,所以它更有可能長期工作。

4

我有完全一樣的問題,通過添加suppressConstructorProperties = true參數(使用你的榜樣)「解決」它:

@Value 
@Wither 
@AllArgsConstructor(suppressConstructorProperties = true) 
public class TestFoo { 
    @JsonProperty("xoom") 
    private String x; 
    private int z; 
} 

傑克遜顯然不喜歡java.beans.ConstructorProperties註釋添加到構造函數。 suppressConstructorProperties = true參數告訴Lombok不要添加它(默認情況下它會)。

+3

'suppressConstructorProperties'現在已經過時:-( – lilalinux

0

我有我所有的類註釋是這樣的:

@JsonAutoDetect(fieldVisibility = Visibility.ANY) 
@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@Data 
@Accessors(fluent = true) 
@NoArgsConstructor 
@AllArgsConstructor 

它曾與龍目島所有和傑克遜版本,至少一兩年。

例子:

@JsonAutoDetect(fieldVisibility = Visibility.ANY) 
@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@Data 
@Accessors(fluent = true) 
@NoArgsConstructor 
@AllArgsConstructor 
public class Person { 
    String id; 
    String first; 
    String last; 
} 

就是這樣。龍目島和傑克遜一起玩耍就像一個魅力。

0
@JsonInclude(JsonInclude.Include.NON_NULL) 
@Data 
public class Person { 
    String id; 
    String first; 
    String last; 
} 

除了Data Class之外,它應該是正確配置ObjectMapper的。 在這種情況下,它是工作確定了ParameterNamesModule配置和設置欄目的知名度和Creator方法

om.registerModule(new ParameterNamesModule()); 
    om.setVisibility(FIELD, JsonAutoDetect.Visibility.ANY); 
    om.setVisibility(CREATOR, JsonAutoDetect.Visibility.ANY); 

然後按預期它應該工作。

2

@AllArgsConstructor(suppressConstructorProperties = true)已棄用。定義lombok.anyConstructor.suppressConstructorProperties=truehttps://projectlombok.org/features/configuration)並將POJO的lombok註釋從@Value更改爲@Data + @NoArgsConstructor + @AllArgsConstructor適合我。

-1

如果你想要不可變但是使用lombok和jackson的json可序列化的POJO。 在您的龍目島建造者@JsonPOJOBuilder上使用jacksons新註釋(withPrefix =「」) 我試過這個解決方案,它工作得很好。 樣品使用

import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 
    import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 
    import lombok.*; 

    @JsonDeserialize(builder = Detail.DetailBuilder.class) 

    @Value 

@Builder 
public class Detail { 

    private String url; 
    private String userName; 
    private String password; 
    private String scope; 

    @JsonPOJOBuilder(withPrefix = "") 
    public static class DetailBuilder { 

    } 
} 
+0

一個解決方案的鏈接是值得歡迎的,但請確保你的答案是有用的,沒有它:[添加背景周圍的鏈接](// meta.stackexchange .com/a/8259),所以你的同行會有一些想法它是什麼以及爲什麼它在那裏,然後引用你鏈接到的頁面最相關的部分,以防目標頁面不可用。[答案很少多於一個鏈接可能會被刪除。](// stackoverflow。com/help/deleted-answers) – geisterfurz007

+0

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/18828665) – JimHawkins

+1

刪除鏈接並添加了我的工作示例 –