龙目岛1.18.0和杰克逊2.9.6没有合作 [英] Lombok 1.18.0 and Jackson 2.9.6 not working together

查看:142
本文介绍了龙目岛1.18.0和杰克逊2.9.6没有合作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新后反序列化失败。

我从 Spring 1.5.10更新了我的微服务.RELEASE Spring 2.0.3.RELEASE 并且还从<$更新了 lombok c $ c> 1.16.14 至 1.18.0 jackson-datatype-jsr310 2.9.4 2.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字符串 -

The JSON string -

{"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);

用于反序列化的方法 -

The method used to deserialize -

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 。)

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.)

解决方案3:
将Jackson的构建器支持与lombok的 @Builder 结合使用,如这里

这篇关于龙目岛1.18.0和杰克逊2.9.6没有合作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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