首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【随笔】Jackson 反序列化报错的解决方案

【随笔】Jackson 反序列化报错的解决方案

作者头像
框架师
发布2025-09-19 11:25:30
发布2025-09-19 11:25:30
2570
举报
文章被收录于专栏:墨白的Java基地墨白的Java基地

在 Spring Boot 项目开发过程中,我们经常会遇到 前端传参与后端 DTO 定义不一致 的情况。 最近在项目中就踩到这样一个坑:前端传输 JSON 数据时,后端 Jackson 反序列化直接报错。

一、报错信息

代码语言:javascript
复制
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: 
Cannot deserialize value of type `java.lang.String` from Array value (token `JsonToken.START_ARRAY`) 
at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 4230] 
(through reference chain: com.ruoyi.manage.task.domain.dto.TaskUpdateDTO["images"])

从报错可以看出:

  • Jackson 期望反序列化为 String 类型
  • 但前端传过来的是一个 ** 数组 ([...])**;
  • 导致无法从 Array 转换成 String,触发了 MismatchedInputException

二、前端 JSON 示例

前端传递的数据如下(简化版):

代码语言:javascript
复制
{
  "images": ["https://********.png"]
}

由于后端的 DTO 字段定义为 String 类型,而前端传了数组,Jackson 无法自动匹配,从而抛出异常。


三、问题原因

总结下来,产生这个问题的根本原因有两点:

  1. 字段类型不一致:后端用 String,但前端传了 Array
  2. 前后端设计不统一:接口规范未对字段类型达成一致。

四、解决方案

根据业务场景,有三种常见解决思路:

1. 后端改为集合类型(推荐 ✅)

如果业务允许上传多张图片,后端 DTO 应该改成集合类型:

代码语言:javascript
复制
@Data
public class TaskUpdateDTO {
    private List<String> images;  // 支持多张图片
}

对应前端传参:

代码语言:javascript
复制
"images": ["https://xx.jpg", "https://yy.jpg"]

这样 Jackson 会自动完成映射,最为推荐。


2. 后端改为单个字段

如果业务只允许单张图片,可以把字段定义为单个 String,并保持字段名和前端一致:

代码语言:javascript
复制
@Data
public class TaskUpdateDTO {
    private String image; // 单数,和前端一致
}

对应前端 JSON:

代码语言:javascript
复制
"image": "https://xx.jpg"

3. 同时兼容单图和多图

如果需要兼容两种情况(既可能是字符串,也可能是数组),可以自定义反序列化器:

代码语言:javascript
复制
@Data
public class TaskUpdateDTO {
    @JsonDeserialize(using = ImageDeserializer.class)
    private List<String> images;  // 兼容单图 / 多图
}

自定义反序列化器:

代码语言:javascript
复制
public class ImageDeserializer extends JsonDeserializer<List<String>> {
    @Override
    public List<String> deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException {
        JsonToken token = p.currentToken();
        if (token == JsonToken.START_ARRAY) {
            return ctxt.readValue(p, new TypeReference<List<String>>() {});
        } else if (token == JsonToken.VALUE_STRING) {
            return List.of(p.getValueAsString());
        }
        return Collections.emptyList();
    }
}

这样,无论前端传:

代码语言:javascript
复制
"images": "https://xx.jpg"

还是:

代码语言:javascript
复制
"images": ["https://xx.jpg", "https://yy.jpg"]

后端都能正确解析为 List<String>

五、总结

  • 单图场景:用 String image
  • 多图场景:用 List<String> images
  • 兼容场景:使用自定义反序列化器。

根本原则是:保持前后端字段名和字段类型一致,否则 Jackson 在反序列化时必然报错

👉 通过这次问题,也提醒我们在接口设计阶段,应尽早约定好字段类型和字段名,避免前后端各自随意定义,导致序列化和反序列化失败。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、报错信息
  • 二、前端 JSON 示例
  • 三、问题原因
  • 四、解决方案
    • 1. 后端改为集合类型(推荐 ✅)
    • 2. 后端改为单个字段
    • 3. 同时兼容单图和多图
  • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档