更新后反序列化失败。
我从我的更新微服Spring 1.5.10.RELEASE来Spring 2.0.3.RELEASE,也更新了lombok从1.16.14到1.18.0和jackson-datatype- jsr310从2.9.4到2.9.6。
Spring 1.5.10.RELEASE
Spring 2.0.3.RELEASE
lombok
1.16.14
1.18.0
jackson-datatype- jsr310
2.9.4
2.9.6
JSON字符串
{"heading":"Validation failed","detail":"field must not be null"}
class
@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停止@ConstructorProperties在版本1.16.20的构造函数上生成(请参阅changelog),因为它可能会破坏使用模块的Java 9+应用程序。该注释包含构造函数参数的名称(编译类时将其删除,因此这是一种变通方法,以便仍可以在运行时检索参数名称)。因为默认情况下现在不生成注释,所以Jackson无法将字段名称映射到构造函数参数。
@ConstructorProperties
解决方案1: 使用@NoArgsConstructor和@Setter,但是您会失去不变性(如果这对您很重要)。
@NoArgsConstructor
@Setter
更新: Just @NoArgsConstructor和@Getter(不带@Setter)也可能会起作用(因为INFER_PROPERTY_MUTATORS=true)。这样,您可以使类至少从常规(非反射)代码中保持不变。
@Getter
INFER_PROPERTY_MUTATORS=true
解决方案2: 使用lombok.config包含line 的文件 ,将 lombok配置为再次生成注释lombok.anyConstructor.addConstructorProperties = true。(如果使用模块,请确保java.desktop位于模块路径上。)
lombok.config
lombok.anyConstructor.addConstructorProperties = true
java.desktop