Lombok 1.18.0 和 Jackson 2.9.6 不能一起工作 [英] Lombok 1.18.0 and Jackson 2.9.6 not working together

查看:37
本文介绍了Lombok 1.18.0 和 Jackson 2.9.6 不能一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新后反序列化失败.

我将我的微服务从 Spring 1.5.10.RELEASE 更新为 Spring 2.0.3.RELEASE 并且还更新了 lombok1.16.141.18.0jackson-datatype-jsr3102.9.42.9.6.

I updated my micro-service from Spring 1.5.10.RELEASE to Spring 2.0.3.RELEASE and also updated the lombok from 1.16.14 to 1.18.0 and jackson-datatype-jsr310 from 2.9.4 to 2.9.6.

JSON 字符串 -

{"heading":"Validation failed","detail":"field must not be null"}

班级 -

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ErrorDetail {

   private final String heading;
   private final String detail;
   private String type;
}

方法调用-

ErrorDetail errorDetail = asObject(jsonString, ErrorDetail.class);

用于反序列化的方法-

import com.fasterxml.jackson.databind.ObjectMapper;
// more imports and class defination.

private static <T> T asObject(final String str, Class<T> clazz) {
    try {
        return new ObjectMapper().readValue(str, clazz);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

错误 -

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.foo.bar.ErrorDetail` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"heading":"Validation failed","detail":"field must not be null"}"; line: 1, column: 2]

推荐答案

Lombok 停止在 1.16.20 版本的构造函数上生成 @ConstructorProperties(请参阅 changelog),因为它可能会破坏使用模块的 Java 9+ 应用程序.该注释包含构造函数参数的名称(它们在编译类时被删除,因此这是一种变通方法,以便在运行时仍然可以检索参数名称).因为现在默认不生成注解,Jackson 无法将字段名称映射到构造函数参数.

Lombok stopped generating @ConstructorProperties on constructors with version 1.16.20 (see changelog), because it might break Java 9+ applications that use modules. That annotation contains the names of the constructor's parameters (they are removed when compiling the class, so that's a workaround so that the parameter names still can be retrieved at runtime). Because the annotation is now not being generated by default, Jackson cannot map the field names to the constructor parameters.

解决方案 1:使用 @NoArgsConstructor@Setter,但你会失去不变性(如果这对你很重要).

Solution 1: Use a @NoArgsConstructor and @Setter, but you will loose immutability (if that's important to you).

更新:@NoArgsConstructor@Getter(没有 @Setter)也可以工作(因为 INFER_PROPERTY_MUTATORS=true).通过这种方式,您可以保持类不可变,至少在常规(非反射)代码中是这样.

Update: Just @NoArgsConstructor and @Getter (without @Setter) may also work (because INFER_PROPERTY_MUTATORS=true). In this way, you can keep the class immutable, at least from regular (non-reflective) code.

解决方案 2:配置 lombok 以再次生成注释,使用包含的 lombok.config 文件lombok.anyConstructor.addConstructorProperties = true 行.(如果您正在使用模块,请确保 java.desktop 在您的模块路径上.)在添加 lombok.config 文件后清理并重新编译.

Solution 2: Configure lombok to generate the annotations again, using a lombok.config file containing the line lombok.anyConstructor.addConstructorProperties = true. (If you are using modules, make sure java.desktop is on your module path.) Clean and recompile after you added the lombok.config file.

解决方案 3:将 Jackson 的构建器支持与 lombok 的 (@Jacksonized) @Builder/@SuperBuilder 结合使用,如 @Randakar 回答这个问题.

Solution 3: Use Jackson's builder support in combination with lombok's (@Jacksonized) @Builder/@SuperBuilder, as described in @Randakar answer to this question.

解决方案 4:使用 javac(Java 8 及更高版本)编译时,将 -parameters 附加到命令.这会将构造函数和方法的参数名称存储在生成的类文件中,以便通过反射检索它们.

Solution 4: When compiling with javac (of Java 8 and above), append -parameters to the command. This will store the parameter names of constructors and methods in the generated class files, so they can be retrieved via reflection.

这篇关于Lombok 1.18.0 和 Jackson 2.9.6 不能一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆