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

诡异的Spring @RequestBody驼峰命名字段映射失败为null问题记录

问题

一个非常常规的Spring Controller,代码如下:

import lombok.RequiredArgsConstructor;@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/config")
public class ConfigController {private final ConfigService configService;@ApiOperation("新增配置")@PostMapping("")public R<ConfigVo> createConfig( /*@Valid*/ @RequestBody ConfigDto dto) {return R.success(configService.createConfig(dto));}
}

DTO定义如下:

import io.swagger.annotations.ApiModel;
import lombok.*;@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("配置")
public class ConfigDto {@NotBlankprivate String appId;private String json;private String mark;
}

Postman模拟一次POST请求:

{"mark": "verifyUserByIdAndName","json": "{}","appId": "a_15c140390de54948af88ad9b39d1fd2f"
}

代码逻辑不对劲,然后通过断点调试,发现appId字段为null:
在这里插入图片描述
WTF???有毒吧。

现象就是驼峰命名的字段解析不出来,映射不上。

@Valid

咨询DeepSeek,一大堆废话。提取到关键词@Valid。

给这个Controller加个@Valid注解,也就是上面的代码片段里被注释的/*@Valid*/,Postman请求报错:
在这里插入图片描述
这个报错是框架类的封装然后返回的。说明Spring(Jackson)确实没有从Postman的request里解析映射出appId字段。

框架类代码片段:

private static final MediaType MEDIA_TYPE = new MediaType("application", "json", StandardCharsets.UTF_8);/*** JSR303 表单参数校验失败* 在Controller层使用@Valid注解*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler({MethodArgumentNotValidException.class})
public ResponseEntity<R<?>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e,HttpServletRequest request) {this.logWarn(e, request, "不合法的参数异常");InvalidField invalidField = getInvalidField(e.getBindingResult());R<InvalidField> invalidFieldR = new R<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "不合法的参数异常", invalidField);return createResponseEntity(HttpStatus.BAD_REQUEST, invalidFieldR);
}private void logWarn(Exception e, HttpServletRequest request, String... msg) {String template = "[Web][有Warn被抛出] >> Warn类=[%s], URI=[%s], 消息=[%s], Warn=[%s]";log.warn(String.format(template, e.getClass().getName(), request.getRequestURI(),ArrayUtil.isEmpty(msg) ? e.getMessage() : ArrayUtil.join(msg, ","), ExceptionUtil.stacktraceToString(e)));
}private InvalidField getInvalidField(BindingResult bindingResult) {if (bindingResult == null) {return null;}FieldError fieldError = bindingResult.getFieldError();if (fieldError == null) {return null;}return InvalidField.builder().fieldName(fieldError.getField()).message(fieldError.getDefaultMessage()).build();
}protected static ResponseEntity<R<?>> createResponseEntity(HttpStatus httpStatus, R<?> body) {return ResponseEntity.status(httpStatus.value()).contentType(MEDIA_TYPE).body(body);
}@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public static class InvalidField {private String fieldName;private String message;
}

断点调试截图:
在这里插入图片描述

workaround

继续询问DeepSeek,又是一大堆废话,提取到关键词@JsonProperty。

一开始并没有关注这个,因为这个注解的使用场景是字段命名不匹配。

试试吧,增加@JsonProperty("appId"),也就是

public class ConfigDto {@NotBlank@JsonProperty("appId")private String appId;
}

能解析到appId字段。


但是!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


这两个地方的命名,明明是一模一样的啊。

分析

为啥呢?

Lombok

不是Lombok的问题,其他字段都没有问题,再说appId是一个非常常规的驼峰命名,又不是isSuccesscAppId这种不规范命名。

编译后的代码如下,没有问题
在这里插入图片描述

调试

在DTO里的字段加断点调试,
在这里插入图片描述
在Controller层加断点调试说明@JsonProperty生效:
在这里插入图片描述

为啥呢??

一个比较相似的blog,不过他这篇里的命名不太规范。

参考

相关文章:

诡异的Spring @RequestBody驼峰命名字段映射失败为null问题记录

问题 一个非常常规的Spring Controller&#xff0c;代码如下&#xff1a; import lombok.RequiredArgsConstructor;Slf4j RestController RequiredArgsConstructor RequestMapping("/api/v1/config") public class ConfigController {private final ConfigService …...

YOLOv10改进,YOLOv10检测头融合RFAConv卷积,添加小目标检测层(四头检测)+CA注意机制,全网首发

摘要 空间注意力已广泛应用于提升卷积神经网络(CNN)的性能,但它存在一定的局限性。作者提出了一个新的视角,认为空间注意力机制本质上解决了卷积核参数共享的问题。然而,空间注意力生成的注意力图信息对于大尺寸卷积核来说是不足够的。因此,提出了一种新型的注意力机制—…...

周末总结(2024/01/18)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意&#xff0c;执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内&#xff0c;职场社交不要放在5min以外 职场的人际关系在面对利…...

LLM - 大模型 ScallingLaws 的迁移学习与混合训练(PLM) 教程(3)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145212097 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…...

【软件开发过程管理规范】需求管理,需求分析,设计开发管理,测试管理(Word)

一、需求管理规程 1 简介 2 过程总体描述 2.1 过程概述 2.2 过程流程图 3 过程元素描述 3.1 准备阶段 3.2 需求调研 3.3 需求分析 软件开发人员及用户往往容易忽略信息沟通&#xff0c;这导致软件开发出来后不能很好地满足用户的需要&#xff0c;从而造成返工。而返工不仅在技术…...

计算机网络 (49)网络安全问题概述

前言 计算机网络安全问题是一个复杂且多维的领域&#xff0c;它涉及到网络系统的硬件、软件以及数据的安全保护&#xff0c;确保这些元素不因偶然的或恶意的原因而遭到破坏、更改或泄露。 一、计算机网络安全的定义 计算机网络安全是指利用网络管理控制和技术措施&#xff0c;保…...

RPA编程实践:Electron实践开始

文章目录 前言闲话少叙&#xff0c;打开官网版本发布安装在 Windows 上安装在 macOS 上安装在 Linux (Ubuntu) 上安装 前言 上回说道&#xff0c;我们electron适合于熟悉web开发&#xff0c;但想要研发桌面应用的人。 但我觉得这个需求应该不是很多。 因为使用electron&#…...

ORB-SLAM2源码学习:MapPoint.cc④: 新增地图点总结

前言 让我们来总结ORB-SLAM2 中的新增地图点。 1.在第一阶段跟踪中的恒速模型跟踪中新增地图点 针对双目相机或RGB-D相机&#xff0c;找出上一帧中具有有效深度值且不是地图点的特征点&#xff0c;将其中较近的点作为上一帧新的临时地图点&#xff0c; 并记录在向扯mlpTempo…...

2025西湖论剑-babytrace

前言 就做了下题目&#xff0c;pwn1/3 都是签到&#xff0c;pwn2 后面绕 ptrace 有点意思&#xff0c;简单记录一下 漏洞分析 子进程中的读/写功能没有检查负数的情况&#xff0c;存在越界读写&#xff1a; void __fastcall get_value(__int64 *int64_arr) {__int64 ll; //…...

绘图专用,26个常见流程图符号及其解释

关注作者 当您设计网站、构建应用程序或绘制业务系统时&#xff0c;您需要一种方法来清晰地绘制步骤和用户流程。虽然您可以使用流程图来概述这些过程&#xff0c;但箭头和方框只能帮助您到目前为止。为了清楚地表达您的意思&#xff0c;您需要流程图符号。 为了帮助解释每个流…...

【个人学习记录】软件开发生命周期(SDLC)是什么?

软件开发生命周期&#xff08;Software Development Life Cycle&#xff0c;SDLC&#xff09;是一个用于规划、创建、测试和部署信息系统的结构化过程。它包含以下主要阶段&#xff1a; 需求分析&#xff08;Requirements Analysis&#xff09; 收集并分析用户需求定义系统目标…...

自学SpringBoot笔记

概念 什么是SpringBoot&#xff1f; Spring Boot 是基于 Spring Framework 的一款开源框架&#xff0c;主要用于简化 Spring 应用程序的开发。它通过提供一系列的 开箱即用的功能 和 自动配置&#xff0c;让开发者可以快速构建生产级别的独立应用程序&#xff0c;而无需手动配…...

03JavaWeb——Ajax-Vue-Element(项目实战)

1 Ajax 1.1 Ajax介绍 1.1.1 Ajax概述 我们前端页面中的数据&#xff0c;如下图所示的表格中的学生信息&#xff0c;应该来自于后台&#xff0c;那么我们的后台和前端是互不影响的2个程序&#xff0c;那么我们前端应该如何从后台获取数据呢&#xff1f;因为是2个程序&#xf…...

[leetcode](找到vector中的特定元素并删除)无重复字符的最长子串

一.找到vector中的特定元素并删除 #include <iostream> #include <vector> #include <algorithm> int main() { // 示例 vector std::vector<int> vec {1, 2, 3, 4, 5, 6}; // 要删除的元素 int aim 3; // 查找元素 auto it std::fin…...

Mockito+PowerMock+Junit单元测试

一、单元测试用途 1、日常开发团队要求规范&#xff0c;需要对开发需求代码进行单元测试并要求行覆盖率达到要求&#xff0c;DevOps流水线也会开设相关门禁阀值阻断代码提交&#xff0c;一般新增代码行覆盖率80%左右。 二、Mock测试介绍 1、Mock是为了解决不同的单元之间由于…...

Ncat: bind to :::7777: Address already in use报错问题解决

问题描述 Ncat: bind to :::7777: Address already in use. QUITTING. 具体解决方法 If you are in linux environment try, Use netstat -tulpn to display the processeskill -9 <pid> This will terminate the process If you are using windows, Use netstat -…...

Docker 搭建mysql 连接超时问题,xxl-job启动mysql连接报错,禁用dns

1.本地连接Navicat报错信息&#xff0c;猜测是navicat默认连接超时导致的&#xff0c;后面换成idea一个插件虽然慢但连接上了 2013 - Lost connection to MySQL server at reading initial communication packet 2.启动xxl-job会报错&#xff0c;网上有人mysql驱动与数据库不匹…...

在线图片像素颜色拾取工具

在线图片像素颜色拾取工具&#xff0c;非常方便的一个工具&#xff0c;无需登录&#xff0c;用完就走。 包括中文和英文版本。 https://getcolor.openai2025.com...

Qt之登录界面(splash)

在上一篇多文档窗口设计(MDI)的基础上增加了一个登录界面&#xff08;splash&#xff09;. 该模块可以扩展为常规的软件登录界面。 界面展示如下 如果用户名和密码输入正确&#xff0c;则调到MDI界面&#xff0c;如果用户名和密码一共输入三次以上&#xff0c;则程序强制退出…...

NotebookLM:Google 最新 AI 笔记助理解析与实战应用

NotebookLM&#xff1a;Google 最新 AI 笔记助理解析与实战应用 在 AI 驱动的生产力工具不断进化的今天&#xff0c;Google 推出的 NotebookLM&#xff08;Notebook Language Model&#xff09;成为了一款备受关注的智能笔记助理。它结合了 Google 的大语言模型&#xff08;LL…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...

2025-05-08-deepseek本地化部署

title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek&#xff1a;小白也能轻松搞定&#xff01; 如何给本地部署的 DeepSeek 投喂数据&#xff0c;让他更懂你 [实验目的]&#xff1a;理解系统架构与原…...