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

2024-04-30 3854阅读

文章目录

  • 一、基础知识铺垫
      • 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如果 method 是 get 或 delete,使用 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 注解获取。适用于 GET 和 DELETE 请求。
                  请求体(Request Body)通过 HTTP 请求的 body 部分传递数据。在 Spring Boot 中使用 @RequestBody 注解获取。适用于 POST , PUT 和 PATCH请求,发送复杂的数据结构。

                  SpringBoot获取数据的方式

                  需要提及的是,单单从“获取数据”的角度,我们可以把Delete和Get归为一类,把Put、Patch、Post归为一类。

                  • 前者在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 主要用于将单个请求参数绑定到方法的参数上,通过指定 value 或 name 属性,你可以明确告诉 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 getUser(@RequestBody Map body) {
                        Long id = Long.valueOf(body.get("userId").toString());
                        String mind = (String) body.get("name");
                        // 业务逻辑
                    }
                    
                    @PutMapping("/users")
                    public R 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 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 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 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 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 允许在一个请求中发送多部分数据,包括文本字段和文件,非常适合文件上传的场景

                      
                        点击上传
                      
                    
                    
                    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('文件上传失败');
                    };
                    
                    
                    @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一样也无关乎get和post。

                    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指定的默认值 ""会被使用。

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


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]