何时解析JSON需要使用@JsonCreator注解方法?
问题分析:为何User类需@JsonCreator而Multiplication类无需?
问题背景
解析User类时遭遇JSON反序列化错误:
@Data public final class User implements Serializable { @JsonProperty("alias") private final String alias; }
报错信息:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `microservices.book.multiplication.domain.User` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `microservices.book.multiplication.domain.User` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 10]
添加带@JsonCreator的构造方法后问题解决:
@Data public final class User implements Serializable { @JsonProperty("alias") private final String alias; @JsonCreator public User(@JsonProperty("alias") String alias){ this.alias = alias; } }
但同是@Data注解修饰的final类Multiplication,无需添加@JsonCreator却能正常解析:
@Data public final class Multiplication implements Serializable { @JsonProperty("factorA") private final Integer factorA; @JsonProperty("factorB") private final Integer factorB; }
核心原因
1. Lombok构造方法生成的差异
Lombok的@Data注解会自动生成全参构造方法,但参数数量不同时,生成的构造方法注解逻辑有区别:
- 对于多参数的
final类(如Multiplication有2个字段),Lombok会为生成的全参构造方法添加@ConstructorProperties注解,该注解会将构造方法的参数名与类的属性名绑定。Jackson可以识别这个注解,通过属性名匹配完成反序列化。 - 对于单参数的
final类(如User只有1个字段),旧版本Lombok不会为生成的构造方法添加@ConstructorProperties注解。此时Jackson无法将JSON字段与构造方法参数关联,导致找不到合适的实例化逻辑。
2. Jackson的反序列化规则
Jackson处理final字段的反序列化时,必须明确字段与构造逻辑的映射关系:
- 若构造方法带有
@ConstructorProperties,Jackson会通过注解中的属性名匹配JSON字段; - 若构造方法无该注解,则需要通过
@JsonCreator配合参数上的@JsonProperty明确参数与JSON字段的对应关系,否则无法完成反序列化。
3. 测试场景的验证逻辑
测试代码中通过JacksonTester序列化MultiplicationResultAttempt对象(包含User和Multiplication实例),反序列化时:
Multiplication的构造方法带有@ConstructorProperties({"factorA", "factorB"}),Jackson可直接匹配JSON中的对应字段完成实例化;- 未添加
@JsonCreator的User类,其构造方法无@ConstructorProperties注解,Jackson无法将alias字段与构造方法参数关联,因此抛出错误。
补充说明
若使用Lombok 1.18.16及以上版本,单参数final类的构造方法也会自动添加@ConstructorProperties注解,此时无需手动添加@JsonCreator即可正常反序列化。
内容的提问来源于stack exchange,提问作者IDK
相关产品推荐
相关产品推荐

