Spring Boot框架中Controller层API接口如何支持使用多个@RequestBody注解接受请求体参数

一、前言

众所周知,在Spring Boot框架中,Controller层API接口编码获取请求体参数时,在参数上会使用@RequestBody注解;如果一次请求中,请求体参数携带的内容需要用多个参数接收时,能不能多次使用@RequestBody注解呢?

下面我们先测试一下,参考代码:

package com.learn.springboot.controller;import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RequestBodyController {@Getter@Setter@ToStringstatic class User {private Integer age;private String name;}@Getter@Setter@ToStringstatic class Home {private String addr;private String phone;}@Getter@Setter@ToStringstatic class Car {private String number;}@RequestMapping("/req/test")public String test(@RequestBody User user, @RequestBody Home home, @RequestBody Car car) {return new StringBuilder(user.toString()).append("--").append(home.toString()).append("--").append(car.toString()).toString();}
}

PostMan进行请求:
在这里插入图片描述

服务端后端日志:
在这里插入图片描述

由上面的测试代码可以看出,Spring Boot框架原生是不支持多个参数使用@RequestBody注解的,那么要怎么做才能支持呢?

二、Spring Boot支持多个@RequestBody注解接收参数

1. 增加HttpServletRequest对象输入流获取参数逻辑适配器
import cn.hutool.core.io.IoUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;public class MultiRequestBodyWrapper extends HttpServletRequestWrapper {private final byte[] paramBody;public MultiRequestBodyWrapper(HttpServletRequest request, ServletResponse response) throws IOException {super(request);request.setCharacterEncoding(StandardCharsets.UTF_8.name());response.setCharacterEncoding(StandardCharsets.UTF_8.name());paramBody = IoUtil.readBytes(request.getInputStream(), false);}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(paramBody);return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic int available() throws IOException {return paramBody.length;}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}};}
}

2. 定义请求过滤器,使定义的适配器生效

import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;public class MultiRequestBodyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {ServletRequest requestWrapper = null;// 拦截请求格式是JSON格式的报文if (request instanceof HttpServletRequest&& StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {requestWrapper = new MultiRequestBodyWrapper((HttpServletRequest) request, response);}if (null == requestWrapper) {chain.doFilter(request, response);} else {chain.doFilter(requestWrapper, response);}}
}

3. 配置过滤器,使自定义Filter生效

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MultiRequestBodyFilterConfig {@Beanpublic FilterRegistrationBean multiRequestBodyFilterRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new MultiRequestBodyFilter());registration.addUrlPatterns("/req/*");registration.setName("multiRequestBodyFilter");return registration;}}

4. 重启应用,功能测试

代码:

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class RequestBodyController {@Getter@Setter@ToStringstatic class User {private Integer age;private String name;}@Getter@Setter@ToStringstatic class Home {private String addr;private String phone;}@Getter@Setter@ToStringstatic class Car {private String number;}@RequestMapping("/req/test")public String test(@RequestBody User user, @RequestBody Home home, @RequestBody Car car) {return new StringBuilder(user.toString()).append("--").append(home.toString()).append("--").append(car.toString()).toString();}
}

PostMan请求:
在这里插入图片描述

通过测试结果可以看到,此时多个@RequestBody修饰参数进行请求体接收的功能就实现啦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/628165.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法---在一个数组中找出相同个数最多的数

在一个数组中找出相同个数最多的数 面试中被问到的: 在一个数组中找出相同个数最多的数,[1, 1, 1, 2, 2, 3]返回1 思路 创建一个Map,将数组元素的值作为key,出现的次数作为value 如果map的value之前不存在为空,则val…

跟我学java|Stream流式编程——并行流

什么是并行流 并行流是 Java 8 Stream API 中的一个特性。它可以将一个流的操作在多个线程上并行执行,以提高处理大量数据时的性能。 在传统的顺序流中,所有的操作都是在单个线程上按照顺序执行的。而并行流则会将流的元素分成多个小块,并在多…

微信小程序 全局配置||微信小程序 页面配置||微信小程序 sitemap配置

全局配置 小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。 以下是一个包含了部分常用配置选项的 app.json : {"pages": ["pages/index/index",&q…

归并排序算法(Java实现)

1.归并排序算法思想 也称合并排序算法,是将两个或两个以上的有序数据序列合并成一个新的有序数据序列。该算法采用分治法(Divide and Conquer)的思想,将待排序的序列分成若干个子序列,分别对子序列进行排序&#xff0…

十五.流程控制与游标

流程控制与游标 1.流程控制1.1分支结构之IF1.2分支结构值CASE1.3循环结构之LOOP1.4循环结构之WHILE1.5循环结构之REPEAT1.6跳转语句之LEAVE语句1.7跳转语句之ITERATE语句 2.游标2.1什么是游标2.2使用游标步骤4.3举例4.5小结 1.流程控制 解决复杂问题不可能通过一个 SQL 语句完…

linux系统服务器A读取远程linux系统服务器B文件(以cv读图文件为列)

文章目录 前言一、读取远程文件 二、应用解释 前言 当一个服务器需要处理另一个服务器上已知图像的绝对路径时,可以使用 Paramiko 库连接到远程服务器并读取图像,然后使用 OpenCV(cv2)库在本地服务器上加载和处理图像。以下是示例…

C# Winform翻牌子记忆小游戏

效果 源码 新建一个winform项目命名为Matching Game,选用.net core 6框架 并把Form1.cs代码修改为 using Timer System.Windows.Forms.Timer;namespace Matching_Game {public partial class Form1 : Form{private const int row 4;private const int col 4;p…

简单介绍JDK、JRE、JVM三者区别

简单介绍JDK vs JRE vs JVM三者区别 文编|JavaBuild 哈喽,大家好呀!我是JavaBuild,以后可以喊我鸟哥,嘿嘿!俺滴座右铭是不在沉默中爆发,就在沉默中灭亡,一起加油学习,珍惜现在来之不…

Python:正则表达式之re.group()用法

Python正则表达式之re.group()用法学习笔记 正则表达式是在处理字符串时非常有用的工具,而re.group()是在匹配到的文本中提取特定分组内容的方法之一。 1. re.group()的基本用法 在正则表达式中,通过圆括号可以创建一个或多个分组。re.group()用于获取…

【samba】Ubuntu20.04安装 error255解决方法

目录 使用samba报错 net usershare returned error 255时(如下图)解决方法如下: 1、安装 Samba 服务: 2、配置 Samba 共享: 3、设置 Samba 用户密码: 4、重启 Samba 服务: 6、在 Windows 上…

mysql 下载和安装和修改MYSQL8.0 数据库存储文件的路径

一、第一步:下载步骤 下载链接:MySQL :: Download MySQL Installer 选择版本8.0.35,社区版, 点击 Download 下载 安装包 二、第二步:安装步骤 添加环境变量,C:\Program Files\MySQL\MySQL Server 8.0\bin 可以点开MySQL 8.0 Co…

Linux知识点易错点总结(1)

linux 2.6.* 内核默认支持的文件系统:ext3 ext2 ext4 xfsext2:全称Linux extended file system, extfs,即Linux扩展文件系统,ext2为第二代xfs:XFS一种高性能的日志文件系统,2000年5月,Silicon Graphics以GNU通用公共许可证发布这套…

C++基础1

一、形参带默认值的函数 二、inline内联函数 内联函数是一种在编译器处理时,将函数的实际代码插入到调用处的方法。通常,函数调用涉及一定的开销,包括保存和恢复调用现场、跳转到函数的代码位置等。而内联函数通过在调用处直接插入函数的代码…

Django的模板语言

文章目录 模板语法变量标签过滤器注释 组件引擎模板上下文加载器上下文处理器 模板引擎的支持配置用法引擎内置后端 模板 作为一个网络框架,Django 需要一种方便的方式来动态生成 HTML。最常见的方法是依靠模板。一个模板包含了所需 HTML 输出的静态部分&#xff0…

Centos7安装K8S

Centos7安装K8S 安装过程中没有出现的错误可以往下 根据以前一些博主写的博客,在小阳翻了不下几十篇博客之后,我果断是放弃了,于是找到了官网地址,然后也有坑 1. 关闭防火墙 systemctl stop firewalld systemctl disable firew…

MySQL的各种日志

目录 一、错误日志 二、二进制日志 1、介绍 2、作用 3、相关信息 4、日志格式 5、查看二进制文件 6、二进制日志文件删除 三、查询日志 四、慢日志 一、错误日志 记录MySQL在启动和停止时,以及服务器运行过程中发生的严重错误的相关信息,当数据库…

Hive使用shell调用命令行特殊字符处理

1.场景分析 数据处理常用hive -e的方式,通过脚本操作数仓,过程中常常遇到特殊字符的处理,如单双引号、反斜杠、换行符等,现将特殊字符用法总结使用如下,可直接引用,避免自行测试的繁琐。 2.特殊字符处理 …

16.桥接模式

桥接模式 介绍 桥接模式是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立变化。这种模式通过组合的方式来实现,而不是继承。桥接模式通过将抽象和实现解耦,从而实现抽象和实现的分离,使得系统更加…

Java基础-Java基础知识-运算符-笔记

1.运算符 算数运算符&#xff1a; - * / % 赋值运算符&#xff1a; 定义变量的语法规则&#xff1a;类型 变量名 变量值 比较运算符&#xff1a;> < > < ! 逻辑运算符&#xff1a; &&&#xff1a;断路与&#xff0c;两边全…

Java零基础——Vue基础篇

1.【熟悉】Vue简介 1.1 简介 它是一个构建用户界面单页面的框架 Vue是一个前端框架 https://www.pmdaniu.com/#file UI网站 UI 一般开发者使用蓝湖 工具 看着UI图 写接口 https://lanhuapp.com/web/#/item 是一个轻量级的MVVM&#xff08;Model-View-ViewModel&#xff…