Spring Boot Jackson 反序列化 VO 类报错及解决方案
在 Spring Boot 项目中,前端发送 JSON 请求到后端时,常常会遇到类似如下异常:
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Cannot construct instance of `com.xzsoft.blog.web.model.vo.article.QueryIndexArticlePageListReqVO`
(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
本文将带你分析原因并给出解决方案。
1. 异常原因分析
以 QueryIndexArticlePageListReqVO
为例:
@Data
@SuperBuilder
@AllArgsConstructor
public class QueryIndexArticlePageListReqVO extends PageRequestVO {
private String keyword;
}
报错原因:
-
缺少无参构造器
- Jackson 默认反序列化 JSON 时,需要通过 无参构造器 创建对象,然后再通过 setter 设置属性。
-
使用 @SuperBuilder 或全参构造器
- Builder 并不被 Jackson 默认支持,
@AllArgsConstructor
生成的全参构造器无法直接用于 JSON 反序列化。
- Builder 并不被 Jackson 默认支持,
2. 解决方法
方法 1:添加无参构造器(推荐)
在类上添加 @NoArgsConstructor
:
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class QueryIndexArticlePageListReqVO extends PageRequestVO {
private String keyword;
}
- 这样 Jackson 就能正常反序列化 JSON。
- 兼容前端请求体发送如下 JSON:
{
"page": 1,
"pageSize": 10,
"keyword": "Java"
}
方法 2:使用 @JsonCreator + @JsonProperty
如果想使用全参构造器,也可以在构造器上添加注解:
@Data
public class QueryIndexArticlePageListReqVO extends PageRequestVO {
private String keyword;
@JsonCreator
public QueryIndexArticlePageListReqVO(
@JsonProperty("keyword") String keyword,
@JsonProperty("page") Integer page,
@JsonProperty("pageSize") Integer pageSize) {
super(page, pageSize);
this.keyword = keyword;
}
}
- 这种方法需要手动绑定每个字段。
- 适合对象属性复杂或者不想加无参构造器的场景。
3. 前端发送 JSON 示例
对应前端 TypeScript 对象:
export interface PageRequestVO {
page?: number;
pageSize?: number;
}
export interface QueryIndexArticlePageListReqVO extends PageRequestVO {
keyword?: string;
}
// Vue 3 示例
const query: QueryIndexArticlePageListReqVO = {
page: 1,
pageSize: 10,
keyword: 'Java'
}
axios.post('/article/pageList', query)
.then(res => console.log(res.data))
- 后端 VO 类加上
@NoArgsConstructor
后,可以正确接收此 JSON。
4. 总结
- 异常原因:Jackson 需要无参构造器来反序列化 JSON。
- 推荐解决方案:在 VO 类上添加
@NoArgsConstructor
。 - 替代方案:使用
@JsonCreator
+@JsonProperty
注解全参构造器。 - 前端发送 JSON 时,需要字段名与 VO 类属性一致。
这样处理后,Spring Boot 接口就能安全地接收前端 JSON 请求,避免 Cannot construct instance
错误。