• 【SpringBoot】SpringBoot怎么接收前端传递过来的数组


    文章目录


    一、错误经过

    写项目时,需要接收前端传过来的数组,于是用了往常接收字符串,数字等简单类型的方式接收,代码运行后报错。

    最初的错误代码

    前端代码

    var itemList = ['31', '32', '33', '34', '35'];
    
    $.ajax({
        type: 'post',
        dataType: 'json',
        data: {
            "payItem": itemList,  // 支付项目编号
            "payWay": 0,    // 支付方式
            "patientIdentity": "421023111101010011"	// 身份证号
        },
        url: '/pay',
        success: function (data) {
            alert(data.msg);
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    控制器代码

    @RequestMapping("/pay")
    @ResponseBody
    public Map payApp(String[] payItem, Integer payWay, String patientIdentity, HttpServletRequest request) throws Exception {
        Map parameter = new HashMap<>();
    
        System.out.println(Arrays.toString(payItem));
        System.out.println(payWay);
        System.out.println(patientIdentity);
        
        parameter.put("msg", "ok");
        return parameter;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    错误的请求信息

    请求信息

    参数

    参数


    多次尝试

    1. 将前端请求方式修改成get——>没用;

    2. 将前端的itemList使用JSON.stringify(itemList)转化一下?——>没用,只是参数名变了+传递参数转换成了JSON字符串参数


    二、分析

    后端接受参数的三种方式

    1. @RequestBody
    2. @RequestParam
    3. 不写注解修饰直接接收

    请求中的三种内容类型

    内容类型

    说明

    application/x-www-form-urlencoded

    【默认方式,jQuery默认也是这个,可设置contentType属性进行修改】浏览器原生的表单,值为urlencoded之后的 key1=value1&key2=value2…

    multipart/form-data

    浏览器原生的文件表单,用于传输文件

    application/json

    常用的请求头格式,值为json串 {“key1”:“value1”,“key2”:“value2”…}

    接收参数的三种方式对于三种内容类型的解析情况(不全,有几种我不知道)

    内容类型

    @Requestbody

    @RequestParam

    不写注解

    说明

    application/x-www-form-urlencoded

    能解析

    能解析

    能解析

    SpringMVC会自动进行解析,所以通常用@RequestParam或不写注解。

    multipart/form-data

    不能解析

    application/json,application/xml等

    能解析

    SpringMVC不会自动进行解析,所以必须要加@requestbody注解


    Get请求和Post请求的区别

    1. 参数/数据 存放位置不同。

      Get请求是把参数放在URL中(无请求体),会将数据暴露在请求地址上;而Post请求是通过请求体RequestBody来传递参数,象对安全;

    2. 发送请求的步骤不同。

      GET:浏览器会将http的header与data一并发出去,服务器直接响应200(并返回数据);

      POST:浏览器先发送Header,当服务器响应了100之后,浏览器再发送data,最后服务器才响应200(返回数据)——>分了两步


    @Requestbody和@RequestParam的区别

    • @RequestBody:用来接收前端传递给后端的json字符串中的数据(数据在请求体中)——>所以只能发送POST请求;

    • @RequestParam:将请求参数绑定到你控制器的方法参数上(是SpringMVC中接收普通参数的注解);

    • @RequestBody只能有一个,@RequestParam可以有多个。


    @RequestParam写与不写的区别

    // 方式一:
    public void test(Integer payWay)
        
    // 方式二:
    public void test(@RequestParam Integer payWay)
        
    // 方式三:
    public void test(@RequestParam("pay") Integer payWay)
    public void test(@RequestParam(value = "pay") Integer payWay)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 方式一:不写时,前端的参数名需要和后端控制器的变量名保持一致才能生效;
    2. 方式二:写时,前端传过来的参数必须有 payWay ,不然就会报错。可以加上required = false设置为非必传;
    3. 方式三:指定参数名,这个值与前端的参数名对应即可。

    三、解决示例代码

    方式一:使用@RequestParam

    前端代码:

    var itemList = ['31', '32', '33', '34', '35'];
    
    $.ajax({
        type: 'post',	// get、post都行
        dataType: 'json',
        data: {
            "payItem": itemList,  // 支付项目编号
            "payWay": 0,    // 支付方式
            "patientIdentity": "421023111101010011"	// 身份证号
        },
        url: '/pay',
        success: function (data) {
            alert(data.msg);
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    后端代码

    @RequestMapping("/pay")
    @ResponseBody
    public Map payApp(@RequestParam(value = "payItem[]") String[] payItem, Integer payWay, String patientIdentity) {
        Map parameter = new HashMap<>();
        for (String item : payItem) {
            System.out.println(item);
        }
        parameter.put("msg", "ok");
        return parameter;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注意:细心的可以发现,这里@RequestParamvalue值为什么会是payItem[]怪异的“姿势”?

    其实答案在前面就已经知道了,使用浏览器的开发者工具——>网络——>访问链接——>荷载,可以看到前端传递的参数如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传参数

    没错这就是为什么value = "payItem[]"的原因。


    方式二:使用@RequestBody

    思路:由于使用@RequestBody必须为post请求,且请求内容必须为application/json的,且只能使用一个,所以我们其余参数使用url拼接的方式接收。

    即用@RequestBody接收post请求方式传递过来的数据,其余参数使用”伪get“方式传递。

    前端代码

    $.ajax({
        type: 'post',	// 1、必须为post请求
        dataType: 'json',
        contentType: "application/json",	// 2、内容格式必须设置为 application/json
        data: JSON.stringify(itemList),	// 3、参数只能有一个,且被stringify转换
        url: '/pay?' + 'payWay=' + payWay + '&patientIdentity=' + $('#patient-id').val(),
        success: function (data) {
            if (data.status === 'ok') {
                alert(data.msg);
                location.href = 'pay-main.html'
            } else {
                alert(data.msg);
            }
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    【关于第三点】当dataType指定为json后,1.4+以上的jquery版本对json格式要求更加严格。如果不是严格的json格式,就不能正常执行success回调函数。

    即写法data: { “ids” : JSON.stringify(str) } 是错误的,正确写法是data:JSON.stringify(str)。

    后端代码

    @RequestMapping("/pay")
    @ResponseBody
    public Map payApp(@RequestBody String[] payItem, Integer payWay, String patientIdentity) {
        Map parameter = new HashMap<>();
        for (String item : payItem) {
            System.out.println(item);
        }
        parameter.put("msg", "ok");
        return parameter;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、总结

    推荐使用方式一,方式二太过于繁琐,且使用”伪get“的形式传递数据会破坏数据的安全性。

    方式一的要点就是:往常我们接收参数时,前端的参数名和后端控制器的变量名是保持一致的,但是传递数组的時候,前端的参数名比较怪异(eg:arry[]),无法简单的与控制器中的变量名对应上,所以需要使用@RequestParam注解显式设置一下。

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    支持线程编排的并行框架AsyncTool
    ubuntu下添加硬盘,分区以及自动挂载
    HTML-DAY2
    JAVA医药进销存管理系统(附源码+调试)
    Softing TCS:高效的诊断模拟解决方案
    联盟营销最佳实践:提高联盟计划的投资回报率
    shell 中 “>“ 与 “>>“ 的区别
    推荐一个C#开发的窗口扩展菜单,支持系统所以窗口
    第1关:图的邻接矩阵存储及求邻接点操作
    python 将数组元素存入.csv文件中;csv内部实现行列转换;
  • 原文地址:https://blog.csdn.net/m0_67403272/article/details/126080666