Spring Boot Jackson 反序列化 VO 类报错及解决方案

发表于 2025-09-19 00:33:13 分类于 默认分类 阅读量 69

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;
}

报错原因:

  1. 缺少无参构造器

    • Jackson 默认反序列化 JSON 时,需要通过 无参构造器 创建对象,然后再通过 setter 设置属性。
  2. 使用 @SuperBuilder 或全参构造器

    • Builder 并不被 Jackson 默认支持,@AllArgsConstructor 生成的全参构造器无法直接用于 JSON 反序列化。

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 错误。