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

一、基础知识铺垫

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();
    }
	@Data
	class 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();
    }
	@Data
	class Query1{
	    String type;
	}
	@Data
	class 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();
    }
	@Data
	class 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();
    }
	@Data
	class 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();
    }
	@Data
	class 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();
    }
	@Data
	class 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();
    }
    
	@Data
	class UserVo{
	    Long userId;
	    List<Item> userOrder;
	}
	@Data
	class 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();
    }
	@Data
	class 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-upload
    action="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指定的默认值 ""会被使用。

在这里插入图片描述

  • 31
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: axiosspringboot都是常用的web开发工具,axios是前端常用的ajax库,而springboot则是后端常用的Java框架。在利用axiosspringboot服务器发送数据时,如果服务器接收到的数据为空,通常有以下几种原因: 1. 前端数据未正确传递。如前端请求数据中未携带正确的参数或者参数格式不正确,导致服务器无法获取数据。 2. 后端代码存在问题。可能是在后端处理数据的代码出现了逻辑错误,未能正确解析获取到的数据。 3. 通信协议问题。axios默认使用的是json数据格式与服务器通信,而如果服务器接收到的是其他类型的数据,则可能出现数据无法解析的问题。 针对此问题,可以采取以下解决措施: 1. 在前端检查请求数据是否正确,确认参数是否正确携带并且格式是否正确。 2. 在后端代码中检查数据处理逻辑是否正确,确认是否能够正确解析数据。 3. 确认前后端通信的数据格式一致,可以通过设置axios请求头来指定数据传输的格式。 总之,要想确保axiosspringboot之间数据正常传输,需要开发者对前后端代码都进行检查与调试,找出问题所在并加以解决。 ### 回答2: 问题描述: 在进行axios请求时,通过post方式将表单数据提交到springboot服务器,但服务器接收到的数据为空。 解决方案: 1. 确认前端发送数据格式是否正确,包括数据字段名、数据类型、数据格式等。注意表单数据需要使用FormData格式发送。 2. 确认后端接收数据的方式是否正确,对于表单数据,可使用@RequestBody注解进行接收。 3. 确认后端代码中是否存在可能引起数据为空的代码逻辑,如使用@RequestParam注解而非@RequestBody进行接收等。 4. 对于数据量较大的情况,可考虑将数据进行分页处理,避免一次性传输过大的数据量。 5. 使用日志记录方式,输出接收到的数据,便于排查问题。 结论: 实现axios请求并不是很难,但在实践中也需要注意一些问题。对于接收数据为空问题,需要从多个方面进行排查,包括前端发送数据格式、后端接收方式以及后端代码实现逻辑等。在排查问题时,需要综合考虑,寻找最终解决方案。 ### 回答3: 在使用 AxiosSpring Boot 服务器进行数据传递时,有时会发现服务器接收到的数据为空。造成这种情况的原因有很多,可以从以下几个方面排查: 1. Axios 请求体设置问题 Axios 默认情况下是将请求数据以 JSON 格式发送到服务器的。如果服务器接收数据的方式不是 JSON 格式,那么就会出现接收数据为空的情况。此时,需要在 Axios请求头中设置 `Content-Type`,并将数据以 form-data 的方式发送到服务器,例如: ``` axios({ method: 'post', url: '/api/user/add', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: qs.stringify(formData) }) ``` 2. 请求地址错误 如果请求地址错误,那么服务器无法接收数据,也就是说即使 Axios 发送数据,服务器也无法正确处理。因此,需要确认请求地址是否正确。 3. Controller 参数设置问题 在 Spring Boot 的 Controller 中接收数据也有很多种方式,常见的有通过 `@RequestParam`、`@PathVariable`、`@RequestBody` 等注解接收参数。如果参数设置不正确,就可能出现无法接收数据的情况。因此,需要确认参数的设置是否正确。 4. 数据类型不匹配 在前端通过表单提交数据时,数据类型通常为字符串,而在后端接收数据时,需要进行相应的类型转换。如果类型不匹配,就可能出现接收数据为空的情况。例如,前端提交的数据是字符串类型的,而后端要求接收的是整型或者枚举类型,此时就需要进行类型转换。 综上所述,当出现 Axios 发送数据Spring Boot 服务器接收数据为空的情况时,需要从以上几个方面进行排查,找出问题所在,逐一解决。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值