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

基于Springboot用axiospost请求接收字符串参数为null的解决方案

问题

今天在用前端 post 请求后端时发现,由于是以 Json对象的形式传输的,后端用两个字符串形参无法获取到对应的参数值

前端代码如下:

axios.post('http://localhost:8083/test/postParams',{a: '1', b:'2'} ,{'Content-Type': 'application/json'}).then(response => {console.log(response.data);}).catch(error => {console.error('There was an error!', error);
});

后端代码如下:

@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {@PostMapping("/postParams")public void postParams(String a, String b) {log.info(String.valueOf(a));log.info(b);}
}

image-20250123171531186

解决

在网上学习了一下,究其原因是Spring Boot 无法直接将 JSON 字符串转换为一个 String 变量, Spring Boot 需要通过相应的机制,将 JSON 字符串解析成可用的 Java 对象或 Map,在学习了某位前辈的文章后,通过自定义注解的方式解决了问题:

​ 总的思路就是,getRequestBody()将请求的json对象字符串先缓存到cache中,然后将该字符串解析成Json对象,在根据对应的方法形参的名字,将值注入进去。

自定义注解类

/*** @author yamu* @version 1.0* @description: 接收前端传的 包装类数据 或 String 自定义注解* @date 2025/1/13 11:05*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestJson {//参数值(对应的键名)String value() default "";
}

定义@RequestJson的方法形参解析器

/*** @author yamu* @version 1.0* @description: 自定义注解 RequestJson 方法形参解析器* @date 2025/1/13 11:07*/
@Component
@Slf4j
public class RequestJsonMethodArgumentResolver implements HandlerMethodArgumentResolver {public static String cache = "";//缓存请求体@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(RequestJson.class);}/*** @description  String 参数注入* @param: parameter* @param: mavContainer* @param: webRequest* @param: binderFactory* @returns Object* @author yamu* @date 2025/1/20 14:33*/@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {RequestJson requestJson = parameter.getParameterAnnotation(RequestJson.class);HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);//未指定映射的键时,默认值为形参名String value = requestJson.value();if (value.isEmpty()) {value = parameter.getParameterName();}JSONObject jsonObject = getRequestBody(request);//遍历完最后一个参数,则清理缓存if (parameter.getMethod().getParameterCount() - 1 <= parameter.getParameterIndex()) {cache = "";}//请求的参数为空,直接返回nullif (jsonObject == null) {return null;}return jsonObject.get(value);}/*** 获取参数列表* @param request* @return*/private JSONObject getRequestBody(HttpServletRequest request) {//cache不为空if (!cache.isEmpty()) {return JSONObject.parseObject(cache);}//字符串拼接成Json字符串StringBuilder sb = new StringBuilder();try {BufferedReader reader = request.getReader();char[] buf = new char[1024];int rd;while ((rd = reader.read(buf)) != -1) {sb.append(buf, 0, rd);}} catch (IOException ex) {log.error(ex.getMessage());}cache = sb.toString();return JSONObject.parseObject(sb.toString());}
}

在WebConfig里注册解析器

@Configuration
@Slf4j
public class WebConfig extends WebMvcConfigurationSupport  {@Autowiredprivate RequestJsonMethodArgumentResolver requestJsonMethodArgumentResolver;/*** @description 配置方法解析器* @param: argumentResolvers* @returns void* @author yamu* @date 2025/1/23 16:00*/@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {argumentResolvers.add(requestJsonMethodArgumentResolver);}
}

在方法形参上加上注解

@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {@PostMapping("/postParams")public void postParams(@RequestJson String a, @RequestJson String b) {log.info(a);log.info(b);}
}

image-20250123174734261

上述方式存在几个问题:

  1. 由于要缓存请求的 Json字符串,所以在每次请求完之后要清除cache,上述方法是在方法形参的最后一个并且加了@RequestJson注解的参数才可以清理
  2. 由于需要对每个参数进行赋值,所以需要对每个要注入的参数都要加上@RequestJson注解
  3. 处理包装类或字符串类时,形参类型需要强一致(不能用Stringl类型接收一个Integer的参数值),同时也无法处理复杂的对象类型

后续在逐渐的深入学习后我会优化上述方式。

相关文章:

基于Springboot用axiospost请求接收字符串参数为null的解决方案

问题 ​ 今天在用前端 post 请求后端时发现&#xff0c;由于是以 Json对象的形式传输的&#xff0c;后端用两个字符串形参无法获取到对应的参数值 前端代码如下&#xff1a; axios.post(http://localhost:8083/test/postParams,{a: 1, b:2} ,{Content-Type: application/jso…...

最长递增——蓝桥杯

1.题目描述 在数列 a1​,a2​,⋯,an​ 中&#xff0c;如果ai​<ai1​<ai2​<⋯<aj​&#xff0c;则称 ai​ 至 aj​ 为一段递增序列&#xff0c;长度为 j−i1。 定一个数列&#xff0c;请问数列中最长的递增序列有多长。 输入描述 输入的第一行包含一个整数 n。…...

【MFC】C++所有控件随窗口大小全自动等比例缩放源码(控件内字体、列宽等未调整) 20250124

MFC界面全自动等比例缩放 1.在初始化里 枚举每个控件记录所有控件rect 2.在OnSize里&#xff0c;根据当前窗口和之前保存的窗口的宽高求比例x、y 3.枚举每个控件&#xff0c;根据比例x、y调整控件上下左右,并移动到新rect struct ControlInfo {CWnd* pControl;CRect original…...

C#标准Mes接口框架(持续更新)

前言 由于近期我做了好几个客户的接入工厂Mes系统的需求。但是每个客户的Mes都有不同程度的定制需求&#xff0c;原有的代码复用难度其实很大。所以打算将整个接入Mes系统的框架单独拿出来作为一个项目使用&#xff0c;同时因为不同的设备接入同一个Mes系统&#xff0c;所以代…...

【Uniapp-Vue3】动态设置页面导航条的样式

1. 动态修改导航条标题 uni.setNavigationBarTitle({ title:"标题名称" }) 点击修改以后顶部导航栏的标题会从“主页”变为“动态标题” 2. 动态修改导航条颜色 uni.setNavigationBarColor({ backgroundColor:"颜色" }) 3. 动态添加导航加载动画 // 添加加…...

SQL 递归 ---- WITH RECURSIVE 的用法

SQL 递归 ---- WITH RECURSIVE 的用法 开发中遇到了一个需求&#xff0c;传递一个父类id&#xff0c;获取父类的信息&#xff0c;同时获取其所有子类的信息。 首先想到的是通过程序中去递归查&#xff0c;但这种方法着实孬了一点&#xff0c;于是想&#xff0c;sql能不能递归查…...

期权帮|如何利用股指期货进行对冲套利?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 如何利用股指期货进行对冲套利&#xff1f; 对冲就是通过股指期货来平衡投资组合的风险。它分为正向与反向两种策略&#xff1a; &#xff08;1&#xff09;正向对冲&#xff…...

INCOSE需求编写指南-第1部分:介绍

第1部分&#xff1a;介绍Section 1: Introduction 1.1 目的和范围 Purpose and Scope 本指南专门介绍如何在系统工程背景下以文本形式表达需求和要求陈述。其目的是将现有标准&#xff08;如 ISO/IEC/IEEE 29148&#xff09;中的建议以及作者、主要贡献者和审稿员的最佳实践结…...

FFPlay命令全集合

FFPlay是以FFmpeg框架为基础&#xff0c;外加渲染音视频的库libSDL构建的媒体文件播放器。 ffplay工具下载并播放视频&#xff0c;可以辅助卡看流信息。 官网下载地址&#xff1a;http://ffmpeg.org/download.html#build-windows 下载build好的exe程序&#xff1a; 此处下载…...

Mono里运行C#脚本34—内部函数调用的过程

本文来分析Mono运行脚本时,会调用一些C实现的函数代码。 而这个过程又是怎么样实现的呢? 比如前面分析的脚本: IL_0000: call string class MonoEmbed::gimme() 在这里会调用C函数实现的MonoEmbed::gimme()函数。 而这个函数是在C程序内部实现,通过下面的代码来注册到运行…...

rust feature h和 workspace相关知识 (十一)

feature 相关作用和描述 在 Rust 中&#xff0c;features&#xff08;特性&#xff09; 是一种控制可选功能和依赖的机制。它允许你在编译时根据不同的需求启用或禁用某些功能&#xff0c;优化构建&#xff0c;甚至改变代码的行为。Rust 的特性使得你可以轻松地为库提供不同的…...

-bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录

终端报错&#xff1a; -bash: ./uninstall.command: /bin/sh^M: 坏的解释器: 没有那个文件或目录原因&#xff1a;由于文件行尾符不匹配导致的。当脚本文件在Windows环境中创建或编辑后&#xff0c;行尾符为CRLF&#xff08;即回车和换行&#xff0c;\r\n&#xff09;&#xf…...

【Redis】Redis入门以及什么是分布式系统{Redis引入+分布式系统介绍}

文章目录 介绍redis的引入 分布式系统单机架构应用服务和数据库服务分离【负载均衡】引入更多的应用服务器节点 单机架构 分布式是什么 数据库分离和负载均衡 理解负载均衡 数据库读写分离 引入缓存 数据库分库分表 引入微服务 介绍 The open source, in-memory data store us…...

C#高级:常用的扩展方法大全

1.String public static class StringExtensions {/// <summary>/// 字符串转List&#xff08;中逗 英逗分隔&#xff09;/// </summary>public static List<string> SplitCommaToList(this string data){if (string.IsNullOrEmpty(data)){return new List&…...

Consul持久化配置报错1067---consul_start

报错都是文件写的有问题或者格式问题&#xff0c;直接复制我的这个改改地址就行 先创建文本文件consul_start.txt--->再复制代码保存---->再把.txt改成.bat 持久化存储的地址在&#xff1a;mydata 注&#xff1a;D:\consul\consul_1.20.2_windows_386改成自己consul的…...

「 机器人 」扑翼飞行器控制策略浅谈

1. 研究背景 • 自然界中的蜂鸟以极高的机动能力著称,能够在短至0.2秒内完成如急转弯、快速加速、倒飞、躲避威胁等极限机动。这种表现对微型飞行器(Flapping Wing Micro Air Vehicles, FWMAVs)具有重要的仿生启示。 • 目前的微型飞行器距离自然生物的飞行能力仍有相当差距…...

Qt信号与槽底层实现原理

在Qt中,信号与槽是实现对象间通信的核心机制, 类似于观察者模式。当某个事件发生后,比如按钮被点击,就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,将想要处理的信号和自己的一个函数(称为槽…...

QT QTableWidget控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…...

Flutter_学习记录_基本组件的使用记录

1.TextWidge的常用属性 1.1TextAlign: 文本对齐属性 常用的样式有&#xff1a; TextAlign.center 居中TextAlign.left 左对齐TextAlign.right 有对齐 使用案例&#xff1a; body: Center(child: Text(开启 TextWidget 的旅程吧&#xff0c;珠珠, 开启 TextWidget 的旅程吧&a…...

基于JAVA的微信点餐小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

2025.6.9总结(利与弊)

凡事都有两面性。在大厂上班也不例外。今天找开发定位问题&#xff0c;从一个接口人不断溯源到另一个 接口人。有时候&#xff0c;不知道是谁的责任填。将工作内容分的很细&#xff0c;每个人负责其中的一小块。我清楚的意识到&#xff0c;自己就是个可以随时替换的螺丝钉&…...

C++中vector类型的介绍和使用

文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...