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

【SpringBoot】SpringBoot怎么接收前端传递过来的数组,第1张

文章目录
  • 一、错误经过
    • 最初的错误代码
      • 前端代码
      • 控制器代码
      • 错误的请求信息
      • 参数
    • 多次尝试
  • 二、分析
    • 后端接受参数的三种方式
    • Get请求和Post请求的区别
    • @Requestbody和@RequestParam的区别
    • @RequestParam写与不写的区别
  • 三、解决示例代码
      • 方式一:使用@RequestParam
      • 方式二:使用@RequestBody
  • 四、总结


一、错误经过

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

最初的错误代码 前端代码
var itemList = ['31', '32', '33', '34', '35'];

$.ajax({
    type: 'post',
    dataType: 'json',
    data: {
        "payItem": itemList,  // 支付项目编号
        "payWay": 0,    // 支付方式
        "patientIdentity": "421023111101010011"	// 身份z号
    },
    url: '/pay',
    success: function (data) {
        alert(data.msg);
    }
})
控制器代码
@RequestMapping("/pay")
@ResponseBody
public Map<String, String> payApp(String[] payItem, Integer payWay, String patientIdentity, HttpServletRequest request) throws Exception {
    Map<String, String> parameter = new HashMap<>();

    System.out.println(Arrays.toString(payItem));
    System.out.println(payWay);
    System.out.println(patientIdentity);
    
    parameter.put("msg", "ok");
    return parameter;
}
错误的请求信息

参数


多次尝试
  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. 方式二:写时,前端传过来的参数必须有 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"	// 身份z号
    },
    url: '/pay',
    success: function (data) {
        alert(data.msg);
    }
})

后端代码

@RequestMapping("/pay")
@ResponseBody
public Map<String, String> payApp(@RequestParam(value = "payItem[]") String[] payItem, Integer payWay, String patientIdentity) {
    Map<String, String> parameter = new HashMap<>();
    for (String item : payItem) {
        System.out.println(item);
    }
    parameter.put("msg", "ok");
    return parameter;
}

注意:细心的可以发现,这里@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);
        }
    }
})

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

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

后端代码

@RequestMapping("/pay")
@ResponseBody
public Map<String, String> payApp(@RequestBody String[] payItem, Integer payWay, String patientIdentity) {
    Map<String, String> parameter = new HashMap<>();
    for (String item : payItem) {
        System.out.println(item);
    }
    parameter.put("msg", "ok");
    return parameter;
}

四、总结

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/742378.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存