接口联调,前端 POST 一段 JSON,后端 Spring Boot 抛 InvalidDefinitionException,后面跟着 Cannot construct instance of com.example.User,末尾还有一句 no Creators, like default constructor, exist。类里全参构造写了,注解也加了,错误照旧。
@JsonCreator 这注解本身不难,麻烦在几个配套条件,缺一个 Jackson 就当没写。
构造器参数名得让 Jackson 看见
Jackson 2.x 默认拿不到构造器参数名。要么 javac 加 -parameters,要么给每个参数补 @JsonProperty。Maven 里在 compiler 插件里加这一项,比在每个类上堆注解省事。
只写 @JsonCreator 不写参数注解,日志里那句 no Creators 就是结果:注解在,字段对不上。
静态工厂和多个 creator 的冲突
@JsonCreator 也能标在 static 工厂方法上,参数同样要标 @JsonProperty。一个类里出现两个 @JsonCreator,启动时会报 conflicting creator,得靠 mode 指定优先级。
Lombok 的 @AllArgsConstructor 生成构造器,同样依赖 -parameters;record 从 Jackson 2.12 起原生支持,不用加注解。
字段命名不一致更隐蔽
前端传 userId,库里字段是 user_id,光加 creator 注解不够,类上要配 @JsonNaming,或者全局开 SNAKE_CASE。这类问题不报异常,反序列化完字段全是 null,查起来更费时间。
还有一种报错长得像 creator 的问题:类型对不上。JSON 里传 12.5,构造器参数是 Integer,抛的是 InvalidFormatException,跟注解一点关系没有,别顺着这个方向查。
排查顺序:先看异常里的类名,再看有没有 @JsonCreator,再看参数注解,最后查命名策略。四步走完基本能定位。
真碰到第三方类改不了源码,写个自定义 JsonDeserializer 挂到模块上,比改字段名靠谱。