当前位置: 首页 > article >正文

前端字段名和后端不一致?解锁 JSON 映射的“隐藏规则” !!!

🚀 前端字段名和后端不一致?解锁 JSON 映射的“隐藏规则” 🌟

嘿,技术冒险家们!👋 今天我们要聊一个开发中常见的“坑”:前端传来的 JSON 参数字段名和后端对象字段名不一致,会发生什么?是默默失败,还是直接炸裂?💥 我将以 Spring 的 PageWithSearch 为例,带你揭开 Jackson 的神秘面纱,还有流程图助阵,快跟我一起探索吧!💪


🎯 第一幕:一场“命名失误”的意外

问题起源

我在开发一个分页查询接口,前端传了个 JSON:

{
  "searchField": "name",
  "searchValue": "John",
  "pageNum": 0,
  "pageSize": 10
}

后端用 PageWithSearch 接收:

@PostMapping("/listInviteCodeByPageWithSearch")
public BaseResult listInviteCodeByPageWithSearch(
        @Valid @RequestBody PageWithSearch pageWithSearch) {
    Page<InviteCode> inviteCodePage = inviteCodeService.findPaginatedInviteCodeByAdminIdAndSearch(7, pageWithSearch);
    return BaseResult.success(inviteCodePage);
}

结果,服务层抛了个 NullPointerException,接口返回:

{
  "code": 500,
  "msg": "分页查询失败:null",
  "data": null
}

啥?明明传了 pageNumpageSize,怎么炸了?🤔


🔍 第二幕:深入代码,寻找线索

关键代码

服务层:

public Page<InviteCode> findPaginatedInviteCodeByAdminIdAndSearch(Integer adminId, PageWithSearch pageWithSearch) {
    PageRequest pageRequest = PageRequest.of(pageWithSearch.getPage(), pageWithSearch.getPageSize());
    // ... 其他逻辑 ...
}

PageWithSearchBasePage

public class PageWithSearch extends BasePage {
    private String field;
    private String value;
    public Integer getPageSize() {
        return this.size;
    }
}

public class BasePage {
    Integer page;
    Integer size;
    public Integer getPage() {
        return page;
    }
    public Integer getSize() {
        return size;
    }
}

初步分析

  • 前端字段pageNumpageSize
  • 后端字段pagesize
  • 问题:字段名不一致,pageWithSearch.getPage()getPageSize() 返回 null,导致 PageRequest.of 自动拆箱时抛出 NullPointerException

🐞 第三幕:Jackson 的“严格规则”

真相揭晓

Spring 默认用 Jackson 处理 JSON 到对象的映射,它的规则很简单:

  • 字段名必须一致:JSON 字段名与 Java 对象字段名大小写敏感匹配。
  • 不一致的结果:未匹配的字段被忽略,对象中对应字段保持默认值(null)。
测试验证

输入:

{
  "pageNum": 0,
  "pageSize": 10
}
  • pageWithSearch.getPage()null(无 page 字段)。
  • pageWithSearch.getPageSize()null(无 size 字段)。
  • PageRequest.of(null, null) → 自动拆箱 → NullPointerException
Mermaid 流程图:映射失败过程
前端: pageNum=0, pageSize=10
Jackson 映射到 PageWithSearch
page 未匹配, size 未匹配
getPage()=null, getPageSize()=null
PageRequest.of(null, null)
自动拆箱抛 NullPointerException
返回 500: '分页查询失败:null'

🔧 第四幕:解决“命名冲突”

为什么会这样?

  • Jackson 的默认行为:严格匹配,不做自动转换。
  • 后端代码:未处理字段名不一致,导致 null 值引发下游问题。

解决方案

方案 1:用 @JsonProperty 指定映射

修改 BasePagePageWithSearch

public class BasePage {
    @JsonProperty("pageNum")
    Integer page;
    @JsonProperty("pageSize")
    Integer size;
    // ... 其他代码 ...
}

public class PageWithSearch extends BasePage {
    @JsonProperty("searchField")
    private String field;
    @JsonProperty("searchValue")
    private String value;
    // ... 其他代码 ...
}
  • 效果
    • 前端用 pageNumpageSizesearchField,后端正确映射。
    • 输入:
      {
        "searchField": "name",
        "pageNum": 0,
        "pageSize": 10
      }
      
      • pageWithSearch.getPage()0
      • pageWithSearch.getPageSize()10
方案 2:全局命名策略

application.yml 中配置:

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE
  • 效果
    • 前端用 page_numpage_size,自动映射到 pagesize
    • 输入:
      {
        "field": "name",
        "page_num": 0,
        "page_size": 10
      }
      
方案 3:服务层防御

即使字段名不一致,也避免异常:

public Page<InviteCode> findPaginatedInviteCodeByAdminIdAndSearch(Integer adminId, PageWithSearch pageWithSearch) {
    Pageable pageable = pageWithSearch.toPageableWithDefault(0, 10); // 默认值保护
    String field = pageWithSearch.getField();
    String value = pageWithSearch.getValue();
    if (!StringUtils.isEmpty(field) && !StringUtils.isEmpty(value)) {
        return inviteCodeRepository.findPaginatedInviteCodeByAdminIdAndFieldAndValue(adminId, field, value, pageable);
    } else {
        return inviteCodeRepository.findByAdminId(adminId, pageable);
    }
}
  • 效果
    • pagesizenull 时,用默认值 0 和 10。
Mermaid 流程图:修复过程
前端: pageNum=0, pageSize=10
方案 1: @JsonProperty
page=0, size=10
PageRequest.of(0, 10)
正常返回数据
方案 3: toPageableWithDefault
page=0, size=10

🌈 第五幕:经验与启发

学到了啥?💡

  1. Jackson 的严格匹配
    • 字段名不一致,后端字段变 null,小心下游逻辑!
  2. 命名约定很重要
    • 前后端要统一字段名,或者用工具桥接差异。
  3. 防御性编程
    • null 是隐患,提前处理是王道。

小建议 🌟

  • 文档化
    • 用 Swagger 或 API 文档明确字段名,减少误解。
  • 日志排查
    log.info("Received: page={}, size={}", pageWithSearch.getPage(), pageWithSearch.getPageSize());
    

🎬 尾声

500 错误的迷雾到揭开字段名不一致的真相,这场 debug 让我对 JSON 映射有了新认识。希望这篇博客能帮你在前后端对接时少踩坑!有问题欢迎留言,咱们一起聊技术!✌️

在这里插入图片描述


http://www.kler.cn/a/592796.html

相关文章:

  • 批量删除 PPT 中的所有图片、某张指定图片或者所有二维码图片
  • 链式二叉树概念和结构
  • GPU视频编解码:X86 DeepStream 视频编解码入门(三)
  • PostgreSQL逻辑复制槽功能
  • 华为全流程全要素研发项目管理(81页PPT)(文末有下载方式)
  • 【从零开始学习计算机科学与技术】计算机网络(六)传输层
  • java后端怎么写好根据角色控制查询不同数据,
  • c++图论(三)之图的遍历
  • 【图论】FLOYD弗洛伊德算法-最短路径
  • js给后端发送请求的方式有哪些
  • 【C++】动态规划从入门到精通
  • C++20 中的同步输出流:`std::basic_osyncstream` 深入解析与应用实践
  • IMX335摄像头驱动注册分析
  • AI学习——卷积神经网络(CNN)入门
  • uniapp笔记-底部和首部标签页菜单生成
  • Java基础编程练习第34题-正则表达式
  • 【源码阅读】多个函数抽象为类(实现各种类型文件转为PDF)
  • docker(1) -- centos镜像
  • FOC——Butterworth (巴特沃斯)数字滤波器(2025.03.18)
  • 【sklearn 04】DNN、CNN、RNN