不能让杰克逊和龙目岛一起工作 [英] Can't make Jackson and Lombok work together
问题描述
我正在尝试结合杰克逊和龙目岛。这些是我的课程:
I am experimenting in combining Jackson and Lombok. Those are my classes:
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(onConstructor=@__(@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);
}
}
这些是我的JAR m加入classpth:
Those are the JARs that I'm adding into the classpth:
-
Lombok: https://projectlombok.org/downloads/lombok.jar (版本1.16.10)
Lombok: https://projectlombok.org/downloads/lombok.jar (version 1.16.10)
杰克逊核心: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.8.2/jackson-core-2.8.2.jar
Jackson databind: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.8.2/jackson-databind-2.8.2。 jar
Jackson databind: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.8.2/jackson-databind-2.8.2.jar
Jackson-lombok: http://repo1.maven.org/maven2/io/paradoxical/jackson-lombok/1.1/jackson-lombok-1.1.jar
Jackson-lombok: http://repo1.maven.org/maven2/io/paradoxical/jackson-lombok/1.1/jackson-lombok-1.1.jar
我正在使用Netbeans进行编译(我不认为这是真的相关,但我正在报告无论如何,这使它完美和忠实再现)。上面的五个JAR保存在项目文件夹中名为 lib
的文件夹中(以及 src
, nbproject
, test
和 build
)。我通过项目属性中的添加JAR /文件夹按钮将它们添加到Netbeans中,它们按照上面列表的确切顺序列出。该项目是标准的Java应用程序类型项目。
I am compiling it with Netbeans (I don't think that this is really relevant, but I am reporting this anyway to make it perfectly and faithfully reproducible). The five JARs above are kept in a folder called "lib
" inside the project folder (along with "src
", "nbproject
", "test
" and "build
"). I added them to Netbeans via the "Add JAR/Folder" button in the project properties and they are listed in the exact order as the list above. The project is a standard "Java application" type project.
此外,Netbeans项目配置为不在编译时保存, 生成调试信息,报告已弃用的API ,跟踪java依赖项,激活注释进程 和激活注释在编辑器中处理。 Netbeans中未明确配置注释处理器或注释处理选项。此外, -Xlint:all
命令行选项在编译器命令行中传递,编译器在外部VM上运行。
Further, the Netbeans project is configured to "do NOT compile on save", "generate debugging info", "report deprecated APIs", "track java dependencies", "activacte annotation proccessing" and "activacte annotation proccessing in the editor". No annotation processor or annotation processing option is explicitly configured in Netbeans. Also, the "-Xlint:all
" command line option is passed in the compiler command line, and the compiler runs on an external VM.
我的javac版本是1.8.0_72,我的java版本是1.8.0_72-b15。我的Netbeans是8.1。
My javac's version is 1.8.0_72 and my java's version is 1.8.0_72-b15. My Netbeans is 8.1.
我的项目编译得很好。但是,它会在执行时抛出异常。异常似乎不是任何容易或明显可修复的东西。这是输出,包括stacktrace:
My project compiles fine. However, it throws an exception in its execution. The exception don't seems to be anything that looks easily or obvious fixable. Here is the output, including the stacktrace:
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 java.beans.ConstructorProperties=@java.beans.ConstructorProperties(value=[x, z]), interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.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 java.beans.ConstructorProperties=@java.beans.ConstructorProperties(value=[x, z]), interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.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
注释,但我无法'让它变得更好。
I already tried about randomly poking with the @Value
and @AllArgsConstructor
annotations, but I couldn't make it any better.
我谷歌了解异常和发现了关于杰克逊的旧bug报告,另一个是开放的,但似乎与其他东西有关。但是,这仍然没有说明这个错误是什么或如何解决它。另外,我在其他地方找不到任何有用的东西。
I google'd the exception and found an old bug report on jackson, and another one that is open, but seems to be related to something else. However, this still do not tells anything about what is this bug or how to fix it. Also, I could not find anything useful looking that somewhere else.
因为我想要做的是lombok和jackson的基本用法,我似乎很奇怪找不到有关如何解决此问题的更多有用信息。也许我错过了什么?
Since what I am trying to do is very basic usage of both lombok and jackson, it seems odd that I couldn't find any more useful information about how to workaround this issue. Maybe I missed something?
除了说不使用lombok 或不使用jackson
Other than just saying "don't use lombok" or "don't use jackson", do anybody has any idea about how to solve this?
推荐答案
如果你想要不可变但是json可序列化的POJO使用隆布克和杰克逊。
在你的lomboks构建器上使用jacksons new注释 @JsonPOJOBuilder(withPrefix =)
我试过这个解决方案,它运行得很好。
样本用法
If you want immutable but a json serializable POJO using lombok and jackson.
Use jacksons new annotation on your lomboks builder @JsonPOJOBuilder(withPrefix = "")
I tried this solution and it works very well.
Sample usage
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Value;
@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 {
}
}
如果你有太多的课程与 @Builder
,你想要不需要样板代码空注释你可以覆盖注释拦截器,使其为空 withPrefix
If you have too many classes with @Builder
and you want don't want the boilerplate code empty annotation you can override the annotation interceptor to have empty withPrefix
mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
if (ac.hasAnnotation(JsonPOJOBuilder.class)) {//If no annotation present use default as empty prefix
return super.findPOJOBuilderConfig(ac);
}
return new JsonPOJOBuilder.Value("build", "");
}
});
您可以使用 @JsonPOJOBuilder $ c删除空的构建器类$ c>注释。
这篇关于不能让杰克逊和龙目岛一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!