探索:为什么数组数据后端确要求前端传递,拼接的字符呢

你们好,我是金金金。

前言

撰写本文是因为好奇,好奇为什么,拼接的字符串数据过去能直接变成数组,好奇为什么让传,拼接的字符串而不是直接传递数组数据,好奇....

探索

  • 首先看get请求,get请求参数一般都是携带在路径后面的,还有一种就是参数直接成为路径的一部分,无非就是这两种,用得较多的一般都是参数携带在路径后面的,下面也将在这种方式上演示

Get请求

  1. 前端传递,拼接的字符串,后端String数组接收

    • code

      java 复制代码
      @RestController
      @RequiredArgsConstructor
      @Slf4j
      @RequestMapping("/user/menu")
      public class CustomMenuController {
        @GetMapping("/add")
        public R<String> addCustomMenu(String[] menus) {
          System.out.println(Arrays.toString(menus));
          return R.success("添加成功");
        }
      }
    • 浏览器访问

    • 控制台输出

    可以看到没有任何问题,为什么传递字符串数据能直接用数组接收呢?

    • 因为 Spring MVC 对数组类型有特殊的处理逻辑。它会自动尝试将同名的查询参数或逗号分隔的字符串转换为数组
  2. 前端传递,拼接的字符串,后端List集合接收

    较多的是这种方式,因为操作集合数据比操作数组要方便的多~

    • code

      java 复制代码
      @RestController
      @RequiredArgsConstructor
      @Slf4j
      @RequestMapping("/user/menu")
      public class CustomMenuController {
        @GetMapping("/add")
        public R<String> addCustomMenu(List<String> menus) {
          System.out.println(menus);
          return R.success("添加成功");
        }
      }
    • 浏览器访问

    • 控制台

    很不幸,报错了:java.lang.IllegalStateException: No primary or single unique constructor found for interface java.util.List
    出错的原因:

    • 在SpringMVC中,当需要接收请求参数时,可以使用@RequestParam注解来指定参数的名称。
    • 对于数组类型的参数,SpringMVC会自动将请求中的参数值转换成数组并将其赋值给对应的形参,因此在数组类型的形参列表中不需要加@RequestParam注解。
    • 而对于集合类型的参数,SpringMVC无法自动将请求中的参数值转换为集合类型,需要使用@RequestParam注解来指定参数的名称,只有你加了这个注解,才会自动将请求中的数组转换为集合类型,这样才能正确的将参数赋值给对应的形参。
    • 既然已经知道了问题产生的原因,来调整一下代码:

      java 复制代码
      @RestController
      @RequiredArgsConstructor
      @Slf4j
      @RequestMapping("/user/menu")
      public class CustomMenuController {
        @GetMapping("/add")
        public R<String> addCustomMenu(@RequestParam("menus") List<String> menus) {
          System.out.println(menus);
          return R.success("添加成功");
        }
      }
    • 浏览器请求

    • 控制台输出

成功了,这次知道原因了吧~ 我们接着看Post类型 ~

Post请求

  1. 前端传递,拼接的字符串,后端String数组接收

    • code
    java 复制代码
    @RestController
    @RequiredArgsConstructor
    @Slf4j
    @RequestMapping("/user/menu")
    public class CustomMenuController {
      @PostMapping("/add")
      public R<String> addCustomMenu(String[] menus) {
        System.out.println(Arrays.toString(menus));
        return R.success("添加成功");
      }
    }
    • 由于是Post请求,我们用PostMan来发起测试

    • 控制台输出

    可以看到和Get请求差不多~ 并无啥不同的地方 请求方式不同罢了

  2. 前端传递,拼接的字符串,后端List集合接收

    • code

      java 复制代码
      @RestController
      @RequiredArgsConstructor
      @Slf4j
      @RequestMapping("/user/menu")
      public class CustomMenuController {
        @PostMapping("/add")
        public R<String> addCustomMenu(@RequestParam("menus") List<String> menus) {
          System.out.println(menus);
          return R.success("添加成功");
        }
      }
    • 由于是Post请求,我们用PostMan来发起测试

    • 控制台输出

      可以看到和Get请求差不多~ 并无啥不同的地方 请求方式不同罢了

  3. post请求还可以接收请求体当中的数据,这种方式下的话是不会自动转换的,需要手动去处理的,所以这种方式建议直接让前端传递数组就行

    • code

      java 复制代码
      @RestController
      @RequiredArgsConstructor
      @Slf4j
      @RequestMapping("/user/menu")
      public class CustomMenuController {
        @PostMapping("/add")
        public R<String> addCustomMenu(@RequestBody CustomMenuAddDTO customMenuAddDTO) {
          System.out.println(customMenuAddDTO);
          return R.success("添加成功");
        }
      }
      java 复制代码
      @Data
      public class CustomMenuAddDTO implements Serializable {
        /**
         * 菜单名称集合
         */
        private List<String> menus;
      }
    • 由于是Post请求,我们用PostMan来发起测试

    • 控制台输出

    请求体方式下,如果前端传递的是menus: "1,2,3",在CustomMenuAddDTO里面定义成String[] 或者List<String> 都是不行的。均会报错!除非类型改成private String menus;那还得手动解析成数组,多麻烦,是不~

结尾

相信此时你对 后端在某些情况下让前端传递逗号拼接的字符串 有所理解了吧~
本篇文章均为个人所写,结论都是验证过的,请放心食用~ 哪里写的不对的,或者是哪里写的不好的,请大佬指出,感谢!

  • 编写有误还请大佬指正,万分感谢。
相关推荐
IT_陈寒18 分钟前
SpringBoot启动慢得像蜗牛?原来是这个配置在捣鬼
前端·人工智能·后端
不才不才不不才2 小时前
Spring 源码系列(29): 20 道高频面试题源码级解析合集
java·后端·spring
索隆zoro2 小时前
Army 的可插拔架构:army-jdbc 与方言模块
java·后端
小蒜学长3 小时前
校园社团招新网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·校园社团招新网站
蜗牛互联网4 小时前
从Barclays扩大Claude部署看受监管软件工程的责任重分配
java·大数据·人工智能·后端·软件工程
周杰伦fans5 小时前
C#对话摘要降低Token消耗
人工智能·后端·c#
做系统的大强6 小时前
脚本说 PASS、OS 读全零 —— 到底是谁在撒谎?
后端·操作系统
code2cat6 小时前
【随笔】MCP资源更新订阅:通知到达以后,Agent怎样刷新旧资料
java·后端·开发工具·ai agent·mcp
Harvil_8 小时前
任务跑一半,API 突然报“对话超长“断流:我给 Agent 修的紧急逃生通道
后端
用户EasyAdminBlazor8 小时前
EasyAdminBlazor SignalR 实时消息源码解析:从 NotificationHub 到站内消息
后端