SpringBoot和Axios数据的传递和接收-Restful完全版

文章目录

  • 一、基础知识铺垫
      • Axios使用
      • HTTP请求方式
      • 数据传输方式
      • SpringBoot获取数据的方式
  • 二、基础传递代码示例
    • (一)Path Variables
    • (二)Get、Delete
      • @RequestParam
      • @ModelAttribute
    • (三)Post、Put、Patch
      • @RequestBody
  • 三、稍微复杂一点的传递
    • (一)数组
    • (二)GET/POST复合型
  • 四、特殊数据
    • (一)文件
    • (二)Cookies

一、基础知识铺垫

Axios使用

使用axios发送请求,一般有三个最常用的属性。

属性含义
url请求的端点 URL
methodHTTP 请求方法(如 get, post, put, delete, patch 等)。
params / data如果 methodgetdelete,使用 params 来传递 URL 查询参数。如果是 post, put, patch,则使用 data 传递请求体数据。通常是一个对象 {}。

HTTP请求方式

Restful风格定义了多种请求方式。

方式简介常用场景
GET请求指定的资源。通常用来获取或查询资源。读取或查询资源,如获取用户列表或特定用户的详细信息。
POST向指定资源提交数据,请求服务器进行处理(如创建或修改)。数据包含在请求体中。创建新资源(如新用户、新帖子),或提交用户数据表单。
PUT用请求体中的数据替换目标资源的所有当前表示。更新现有资源的全部内容,如编辑用户的完整个人信息。
PATCH对资源应用部分修改。更新资源的一部分,如修改用户的邮箱地址或密码。
DELETE删除指定的资源。删除资源,如删除用户账户或帖子。

数据传输方式

方式介绍
URL路径参数(Path Variables通过 URL 的路径部分传递数据。在 Spring Boot 中使用 @PathVariable 注解获取。适用于 RESTful 风格的 API,例如获取特定资源的详情。
查询参数(Query Parameters通过 URL 的查询字符串(?key=value 形式)传递数据。在 Spring Boot 中使用 @RequestParam 注解获取。适用于 GETDELETE 请求。
请求体(Request Body通过 HTTP 请求的 body 部分传递数据。在 Spring Boot 中使用 @RequestBody 注解获取。适用于 POST , PUTPATCH请求,发送复杂的数据结构。

SpringBoot获取数据的方式

需要提及的是,单单从“获取数据”的角度,我们可以把DeleteGet归为一类,把PutPatchPost归为一类。

  • 前者在axios中使用params传递参数,属于Query Parameters
  • 后者在axios中使用data传递参数,属于Request Body
  • 无论是哪一种,都可以有Path Variables

在 Spring Boot(及一般的 HTTP 服务开发)中,将请求分为“GET 体系”和“POST 体系”可能会导致一些混淆,因为每种 HTTP 方法(GET、POST、PUT、PATCH、DELETE 等)都设计有其独特的用途和语义。不过,如果我们从“如何获取请求中的数据”这个角度来看,可以有一种比较宽泛的分类方式,尤其是关注于数据是通过 URL 还是请求体传递。

体系获取数据的常用注解
Path Variables@PathVariable
Get、Delete类@RequestParam@ModelAttribute
Post、Put、Patch类@RequestBody

二、基础传递代码示例

除了特殊的数据类型,普通的数据传递,默认以axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';为策略。

(一)Path Variables

Path Variables数据在url上,无关乎get还是post

return request({url: '/test/users/123',method: 'get'});return request({url: '/test/users/345/info',method: 'post'});
@RestController
@RequestMapping("/test")
public class CourseTestController {@GetMapping("/users/{userId}")public String getUser(@PathVariable String userId) {return "Received GET request for User ID: " + userId;}@PostMapping("/users/{userId}/info")public String updateUser(@PathVariable String userId) {return "Received POST request for User ID: " + userId;}}

(二)Get、Delete

@RequestParam

@RequestParam 主要用于将单个请求参数绑定到方法的参数上,通过指定 valuename 属性,你可以明确告诉 Spring Boot 请求参数的实际名称。

return request({url: '/users',method: 'get',params:{type:"1",status:"2",}});
	@GetMapping("/users")public String getUser(@RequestParam String type, @RequestParam(name = "status") String userStatus) {return "Received GET request for" + type + " " + userStatus;}

@ModelAttribute

利用 @ModelAttribute 注解。这个注解会告诉 Spring Boot,应该将请求中的查询参数自动绑定到方法参数对象的属性上。

return request({url: '/users',method: 'get',params:{type:"1",status:"2",}});
	@GetMapping("/users")public String getUser(@ModelAttribute Query query) {return "Received GET request for" + query.toString();}@Dataclass Query{String type;String status;}

通常情况下,我们会将所有的查询参数封装到一个对象中,而不是分开为两个对象,除非这两个对象在逻辑上代表着完全不同的东西,且您希望显式地区分它们。如果您确实有特定的理由需要这样做,也是可行的。比如第二个Query2表示分页查询时的分页参数

return request({url: '/users',method: 'delete',params:{type:"1",status:"2",}});
	@DeleteMapping("/users")public String deleteUser(@ModelAttribute Query1 query1, @ModelAttribute Query2 query2) {return "Received GET request for" + query1.toString() + query2.toString();}@Dataclass Query1{String type;}@Dataclass Query2{String userStatus;// 如果您希望整个对象通过 @ModelAttribute 来绑定,同时又有个别属性名不匹配// 您可以在后端对象中添加 setter 方法,并在其中处理名称不匹配的问题// 注意:Lombok @Data 注解会生成默认的 setter 方法,// 所以如果使用 Lombok,您需要手动添加一个额外的 setter 方法来处理不匹配的情况public void setStatus(String status) {this.userStatus = status;}
}

(三)Post、Put、Patch

@RequestBody

return request({url: '/users',method: 'post',data:{userId: 123,userName: "John Doe",userAge: 30,userSex: "Male"}
});
    @PostMapping("/users")public String getUser(@RequestBody UserVo userVo) {return userVo.toString();}@Dataclass UserVo{Long userId;String userName;Long userAge;String userSex;}

Spring Boot 后端的 UserVo 类中的属性名和前端传递的 JSON 对象的键名不一致时,可以使用@JsonProperty

return request({url: '/users',method: 'put',data:{userId: 123,userName: "John Doe",userAge: 32,userSex: "Male"}
});
    @PutMapping("/users")public String getUser(@RequestBody UserVo userVo) {return userVo.toString();}@Dataclass UserVo{Long userId;@JsonProperty("userName")String name;Long userAge;String userSex;}
return request({url: '/users',method: 'patch',data:{userId: 123,userAge: 34,}
});
    @PatchMapping("/users")public String getUser(@RequestBody UserVo userVo) {return userVo.toString();}@Dataclass UserVo{Long userId;@JsonProperty("userName")String name;Long userAge;String userSex;}

如果你不想额外写一个类作为@RequestBody的参数,你可以选择使用Map或者JsonNode

@PutMapping("/users")
public R<Boolean> getUser(@RequestBody Map<String, Object> body) {Long id = Long.valueOf(body.get("userId").toString());String mind = (String) body.get("name");// 业务逻辑
}
@PutMapping("/users")
public R<Boolean> getUser(@RequestBody JsonNode body) {Long id = body.get("userId").asLong();String mind = body.get("name").asText();// 业务逻辑
}

三、稍微复杂一点的传递

(一)数组

如果用的是Post,那么一般一切安好。

return request({url: '/users',method: 'post',data:{userId: 123,userOrder: ['1223', '3445', '556'],}
});
    @PostMapping("/users")public String getUser(@RequestBody UserVo userVo) {return userVo.toString();}@Dataclass UserVo{Long userId;List<String> userOrder;}

如果用的是Get,就需要注意默认情况下,Spring Boot 期望列表或数组类型的查询参数以特定的格式传递,例如:userOrder=1223&userOrder=3445&userOrder=556。但在你的例子中,由于是通过 axios 发送请求,并且当你在请求的 params 中包含一个数组时,axios 会将数组转换为 userOrder[0]=1223&userOrder[1]=3445&userOrder[2]=556 的格式,这与 Spring Boot 的默认期望不匹配

return request({url: '/users',method: 'get',params:{userId: 123,userOrder: ['1223', '3445', '556'].join(','),}
});
	@GetMapping("/users")public String getUser(@RequestParam String userId, @RequestParam List<String> userOrder) {return userId + "\n" + userOrder.toString();}

对于数组元素是简单类型,直接用字符’,'拼接即可,变成userOrder=1223,3445,556,Springboot也能匹配。或者可以去参考qs.stringify也就是qs库的用法。

如果数组元素比较复杂呢?如果你仍然坚持使用get,建议去阅读qs使用。一般的做法是用post,可以省去很多麻烦。

return request({url: '/users',method: 'post',data:{userId: 123,userOrder: [{ id: '1223', name: 'Order1' },{ id: '3445', name: 'Order2' },{ id: '556', name: 'Order3' }]}
});
    @PostMapping("/users")public String getUser(@RequestBody UserVo userVo) {return userVo.toString();}@Dataclass UserVo{Long userId;List<Item> userOrder;}@Dataclass Item{String id;String name;}

(二)GET/POST复合型

对于复合型请求,即在URL中通过查询参数(例如分页信息)传递部分数据,同时在请求体中通过JSON传递更复杂的数据(例如筛选条件),Spring Boot可以通过同时使用@RequestParam@RequestBody注解来接收这两种类型的数据。

const pageParams = {page: 1,size: 10
};
return request({url: `/users?page=${pageParams.page}&size=${pageParams.size}`,method: 'post',data:{userId: 123,userName: "Jack"}
});
    @PostMapping("/users")public String getUser(@RequestBody UserVo userVo,@RequestParam("page") int page,@RequestParam("size") int size) {return userVo.toString();}@Dataclass UserVo{Long userId;String userName;}

四、特殊数据

(一)文件

上传文件时,使用的 Content-Type 通常是 multipart/form-data。这种类型允许将请求体中的数据作为一系列部分(parts)发送,每个部分可以包含文件内容或其他数据。这种方式非常适合文件上传,因为它支持在单个请求中发送文件数据及其他表单字段

const formData = new FormData();
formData.append('file', file);
formData.append('filename', file.name);
formData.append('chunkIndex', i.toString());
formData.append('totalChunks', totalChunks.toString());
formData.append('md5', md5);
const rsp = await addChunk(formData);export const addChunk = (data: any) => {return request({url: '/video/chunk',method: 'post',data: data});
};
	@PostMapping(value = "/video/chunk")public R<String> handleChunkUpload(@RequestParam("file") MultipartFile file,@RequestParam("md5") String md5,@RequestParam("filename") String filename,@RequestParam("chunkIndex") int chunkIndex,@RequestParam("totalChunks") int totalChunks) {if (ObjectUtil.isNull(file)) {return R.fail("上传文件不能为空");}Boolean b = mediaFilesService.handleChunkUpload(file, md5);if (b){return R.ok();}else {return R.fail();}}

Vue 3 的框架 Element Plus中,el-upload 组件用于文件上传,它底层使用的也是 multipart/form-data 这种 Content-Type 来上传文件。这是因为 multipart/form-data 允许在一个请求中发送多部分数据,包括文本字段和文件,非常适合文件上传的场景

<template><el-uploadaction="http://example.com/upload":data="extraData":on-success="handleSuccess":on-error="handleError"><el-button size="small" type="primary">点击上传</el-button></el-upload>
</template><script setup>
import { ElMessage } from 'element-plus';
import { ref } from 'vue';// 额外数据
const extraData = ref({userId: "123",description: "这是一个文件描述"
});const handleSuccess = (response, file, fileList) => {// 文件上传成功的回调ElMessage.success('文件上传成功');
};const handleError = (err, file, fileList) => {// 文件上传失败的回调ElMessage.error('文件上传失败');
};
</script>
@RestController
public class FileUploadController {@PostMapping("/upload")public String handleFileUpload(@RequestParam("file") MultipartFile file,@RequestParam("userId") String userId,@RequestParam("description") String description) {return "文件上传成功,用户ID: " + userId + ",描述: " + description;}
}

(二)Cookies

cookies的传递和获取和Path Variables一样也无关乎getpost

document.cookie = "exampleCookie=exampleValue; path=/;";
// 输出当前域下的所有 Cookies
console.log("Current cookies:", document.cookie);return request({url: '/users',method: 'get',withCredentials:true
});
	@GetMapping("/users")public String getUser(@CookieValue(value = "exampleCookie", defaultValue = "") String exampleCookie) {return exampleCookie;}

在这个示例中,用于从接收到的请求中提取名为 exampleCookie的 Cookie 值。如果请求中没有 exampleCookie Cookie,defaultValue指定的默认值 ""会被使用。

在这里插入图片描述

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

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

相关文章

FreeRTOS学习 -- 中断配置

一、什么是中断 中断时微控制器一个很常见的特性&#xff0c;中断是由硬件产生&#xff0c;当中断产生以后CPU就会中断当前的流程而去处理中断服务&#xff0c;Cortex-M内核的MCU提供了一个用于中断管理的嵌套向量中断控制器&#xff08;NVIC&#xff09;。 二、中断优先级分…

土壤湿度传感器:助力农业现代化

随着科技的飞速发展&#xff0c;越来越多的先进技术被应用到农业生产中。其中&#xff0c;土壤湿度传感器作为现代农业的重要工具&#xff0c;正逐渐改变着传统农业的生产方式&#xff0c;成为农业现代化的秘密武器。 精确监测&#xff1a;土壤湿度传感器能够实时、精确地监测土…

WIN7用上最新版Chrome

1.下载WIN10最新版Chrome的离线安装包 谷歌浏览器 Chrome 最新版离线安装包下载地址 v123.0.6312.123 - 每日自动更新 | 异次元软件 文件名称&#xff1a;123.0.6312.123_chrome_installer.exe。 123.0.6312.123_chrome_installer.exe 文件右键解压缩得到 chrome.7z&#x…

树莓派3B长时间不操作屏幕息屏无信号处理

树莓派外接显示器&#xff0c;需长时间展示某个网页&#xff0c;经过一段时间&#xff0c;显示器屏幕会黑掉显示无信号。 需修改 /etc/lightdm/lightdm.conf 配置文件中新增如下两行并重启。 xserver-commandX -s 0 dpms sleep-inactive-timeout0

软考 - 系统架构设计师 - Web 应用真题(2)

问题 1&#xff1a; 淘汰策略&#xff1a;遗留系统技术含量低&#xff0c;业务价值也低&#xff0c;所以需要全面重新开发一个系统来替代遗留系&#xff1b;&#xff08;一般是企业的业务发生了根本变化&#xff0c;遗留系统已经基本不再适应企业运作的需要&#xff1b;或者是遗…

【Python基础】19.eval函数的使用

eval函数 eval()将字符串转变为有效的表达式来求值并返回对应的结果 基础数据计算 In [1]: eval("1 1") Out[1]: 2字符串重复 In [2]: eval (" * * 10") Out[2]: **********字符串转为列表 In [3]: type(eval("[1,2,3,4,5]")) Out[3]: lis…

docker 简单使用

docker 简单使用 一、 docker 安装二、docker 使用1. docker pull 拉取镜像2. docker run 后台运行3. docker ps 查看容器运行状态4. docker exec 进入容器5. exit 退出容器6. docker restar 重启容器7. docker stop 停止运行容器8. docker stop 启动容器9. docker stop 删除容…

nextjs渲染篇

1 服务器组件 默认情况下&#xff0c;Next.js 使用服务器组件。 1.1 服务器组件是如何呈现的&#xff1f; 在服务器上&#xff0c;Next.js 使用 React 的 API 来编排渲染。渲染工作被拆分为多个块&#xff1a;按单个路段和Suspense 每个区块分两个步骤呈现&#xff1a; Re…

Python一键修改目录下所有文件的编码格式

前言 在开发中总会遇到这样的问题&#xff0c;别人的代码采用的编码格式是GBK&#xff0c;而自己的项目的编码格式是UTF-8&#xff0c;如果直接复制过来&#xff0c;就会出现中文乱码的问题&#xff0c;一个个该编码格式又非常麻烦。所以我写了这样一小段简短的代码&#xff0…

Python 中的高阶函数

Python 中的高阶函数是指可以接受函数作为参数&#xff0c;或者返回函数作为结果的函数。这种特性让编程变得更加灵活和功能强大&#xff0c;常见的高阶函数有 map()、filter()、reduce() 和 sorted() 等。 map() 函数&#xff1a; map() 函数接受一个函数和一个可迭代对象&a…

select * from .... for update 使用 防止重复提交/操作

详情点下方链接 for-update笔记链接 注&#xff1a;当选中某一个行的时候,如果是通过主键id选中的。那么这个时候是行级锁。 其他的行还是可以直接insert 或者update的。如果是通过其他的方式选中行,或者选中的条件不明确包含主键。这个时候会锁表。其他的事务对该表的任意一行…

SQLite的PRAGMA 声明(二十三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite从出生到现在&#xff08;发布历史记录&#xff09;&#xff08;二十二&#xff09; 下一篇&#xff1a;用于 SQLite 的异步 I/O 模块&#xff08;二十四&#xff09; PRAGMA 语句是特定于 SQLite 的 SQL 扩…

Valorant 瓦罗兰特更新后进不去游戏?3个解决方法完美解决

Valorant 瓦罗兰特更新后进不去游戏&#xff1f;3个解决方法完美解决 《无畏契约&#xff08;VALORANT&#xff09;》是一款由知名游戏开发商&#xff08;Riot Games&#xff09;开发并且免费的多人射击游戏。游戏背景设定在一个幻想世界中&#xff0c;玩家将探索瓦罗兰大陆上…

面对深度合成技术备案,企业应该如何做好准备?

在这个数字化高速发展的时代&#xff0c;互联网信息服务已经深入我们生活的方方面面。特别是那些应用深度合成技术的互联网信息服务&#xff0c;比如通过算法实现的图像、语音和视频的合成等&#xff0c;现在都需要进行严格的备案。由于备案周期较长&#xff0c;建议涉及这些技…

基于python的二手房数据分析建模及可视化研究,爬取链家二手房数据,可视化分析,房价预测模型

介绍 主要涉及通过爬取济南市链家二手房数据&#xff0c;然后对数据进行处理&#xff0c;包括缺省值处理&#xff0c;高德地图获取二手房地址所属市区&#xff0c;经纬度等数据处理。然后通过python的flask框架编写后端接口&#xff0c;把数据响应给前端。然后前端通过AJAX请求…

Excel:如何对数据列进行码值转换

这里有两种函数可以直接解决&#xff1a; 在需要转码的数据列旁边新建一列&#xff0c;使用如下函数即可 1、函数一 VLOOKUP(H10,B3:C45,2,FALSE) VLOOKUP(需要转码的单元格,key和value所在数据范围,需要转成范围内第几列数据,是否模糊匹配) 这个函数中&#xff0c;key和valu…

Oracal数据库使用

Oracal官网&#xff1a;https://www.oracle.com/database/technologies/instant-client/downloads.html 官网搜索需登陆&#xff1a;https://edelivery.oracle.com/osdc/faces/SearchSoftware 软猫下载&#xff1a;Oracle 19.3 0、linux下安装 Linux系统&#xff08;X64&…

lsof命令——查看进程信息

lsof是一个用于显示系统中打开的文件和进程的命令。它可以列出当前系统中打开文件的相关信息&#xff0c;如进程ID、文件描述符、文件类型、文件大小、文件所属用户、文件的读写状态等等。lsof命令可以帮助用户识别哪些进程正在使用某个文件或目录&#xff0c;以及查看系统中打…

谈谈微前端

相关问题 为什么要用微前端微前端的优缺点 回答关键点 独立开发 独立运行 独立部署 自治 微前端是一种架构理念&#xff0c;它将较大的前端应用拆分为若干个可以独立交付的前端应用。这样的好处是每个应用大小及复杂度相对可控。在合理拆分应用的前提下&#xff0c;微前端能…

基于监控视频的车辆检测

目前常用的基于监控视频的车辆检测方法分为两类&#xff1a;基于运动信息的车辆检测方法和基于特征信息的车辆检测方法。基于运动信息的车辆检测方法主要包括光流法、帧差法和背景法等。基于特征的车辆检测&#xff0c;是以统计机器学习理论为基础的车辆检测方法&#xff0c;通…