当前位置: 首页 > 知识库问答 >
问题:

不能让Jackson和Lombok一起工作

翟嘉年
2023-03-14

我正在试验把杰克逊和龙目岛结合起来。这些是我的课:

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);
    }

}

这些是我添加到类spth中的JAR:

>

  • 龙目岛:https://projectlombok.org/downloads/lombok.jar(1.16.10version)

    此外,Netbeans项目被配置为“保存时不编译”、“生成调试信息”、“报告不推荐使用的API”、“跟踪java依赖项”、“Activacte注释处理”和“编辑器中的Activacte注释处理”。NetBeans中没有显式配置注释处理器或注释处理选项。此外,在编译器命令行中传递“-xlint:all”命令行选项,编译器在外部VM上运行。

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

    我的项目编译得很好。但是,它在执行中抛出异常。例外似乎不是任何看起来容易或明显可以修复的东西。下面是输出,包括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
    

    由于我试图做的是lombok和jackson的非常基本的用法,似乎奇怪的是,我找不到任何关于如何解决这个问题的更有用的信息。也许我错过了什么?

    除了说“不要使用龙目岛”或“不要使用杰克逊”,有没有人知道如何解决这个问题?

  • 共有1个答案

    魏翔
    2023-03-14

    如果您希望使用lombok和Jackson实现不可变但json可序列化的POJO。在您的lomboks builder上使用jacksons的新注释@jsonpojoBuilder(withPrefix=“”)我尝试了这个解决方案,它工作得非常好。示例用法

    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

    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注释移除空的生成器类。

     类似资料:
    • 更新后反序列化失败。 我将我的微服务从更新到,并将从更新为,从更新为。 JSON字符串- 班级 - 方法调用- 用于反序列化的方法 - 错误 -

    • 我正在尝试使用龙目岛和MapStruct配置SpringBoot(v2.6.2),已经配置了maven编译器插件和龙目岛地图结构绑定(注释处理器路径),但龙目岛类尚未创建: pom.xml 尝试使用DI时总是出现未初始化变量错误: 变量xxxx可能尚未初始化

    • 如果我使用以下配置,那么jackson转换器工作(mvc声明是最后) 如果我在dispatcher.xml中使用此配置,那么验证工作,但转换不工作。(mvc声明优先) 非常感谢您的任何帮助。Spring版本4.0.6

    • {“时间戳”:1553613278534,“状态”:400,“错误”:“错误请求”,“消息”:“必需的字符串参数'param2'不存在”,“路径”:“/MyURL/42”} 我希望PUT的工作就像POST一样,但它似乎不是。 不幸的是,我不能将参数作为QueryParam发送,因此我应该维护相同的请求调用,因为我正在重构一个完全以这种方式工作的现有endpoint。

    • 我有一个项目,我正在通过GSON和Volley阅读一些json。我想把我的数据保存在数据库中,我希望Realm是一个好的解决方案。我选择了我的第一个类,它有七个成员变量,所有的Strings和int,并让它扩展RealmObject,并将其中一个int确定为主键。它编译得很好,但是当它运行时,我在日志中得到大量的输出,最终应用程序在显示主要活动之前就崩溃了。GSON似乎不喜欢解析扩展了RealmO

    • 当异常发生在CompletableFuture中时,我试图设置一个默认值,我通过如下方法使其工作: 但是,当我试图在不好的事情发生时异常地使用complete来停止CompletableFuture,并按如下方式跟踪异常时,我无法像刚才那样捕捉到异常。 更新日期2018-06-09谢谢您的帮助,@Daniele 在join()之前封闭的句柄按预期工作。但在这种情况下,