ajax的post请求的前端传参格式以及springboot后端接收参数方式

一、数据准备(想看结论直接翻最后)

1、搭建一个springBoot的后端工程
1.1 创建一个简单的user实体类

在这里插入图片描述

1.2 template目录下添加index.html

在这里插入图片描述

1.3 配置静态资源访问路径
@Component
public class WebConfig implements WebMvcConfigurer {
    /**
     * springboot 无法直接访问静态资源,需要放开资源访问路径。
     * 添加静态资源文件,外部可以直接访问地址
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/templates/");       
    }
}
1.4 controller编写,创建接收参数的controller
@RequestMapping("/user")
@RestController
public class UserController {
}

二、后端实体类接收参数

1、后端添加add方法(注意@RequestBody注解,表明这是一个请求体数据)
@PostMapping("/add")
public Object addUser(@RequestBody User user){
    return user;
}
2、 前端代码,这里使用了vue+elementui的form表单

在这里插入图片描述

add1: function () {
    var that = this;
    console.log(that.form.name, that.form.sex);
    axios({
        method: 'post',
        url: "http://localhost:7777/test-request/user/add",
        data: {
            name: that.form.name,
            sex: that.form.sex
        }
    }
         ).then(function (result) {
        that.result = result;
        alert(result)
    });
}

在我们不对axios的请求头进行设置的时候,axios的post请求默认请求头中Content-Type类型为application/json

3、错误情况
3.1 后端实体类接收参数,但是缺少注解@RequestbBody注解,前端使用默认的Content-Type类型(application/json)
@PostMapping("/add")
public Object addUser(User user){
	return user;
}

接口响应结果:

在这里插入图片描述

可以看出此时虽然不会报错,但后端无法解析前端传来的json数据,返回的数据均为null

3.2 后端使用@RequestParam方式接收参数,前端使用默认的Content-Type类型(application/json)
@PostMapping("/add")
public Object addUser(@RequestParam("name") String name,
                      @RequestParam("sex") String sex){

    User user=new User();
    user.setName(name);
    user.setSex(sex);
    return user;
}

后段响应结果

在这里插入图片描述

{“timestamp”:“2021-09-10T02:56:40.430+0000”,“status”:400,“error”:“Bad Request”,“message”:“Required String parameter ‘name’ is not present”,“path”:"/test-request/user/add"}

此时报错400,后端报错请求参数name找不到,但是前端明明传了name的值,说明后端还是无法解析此时的参数

3.3 后端去掉@RequestParm注解,Content-Type类型改为(application/x-www-form-urlencoded; charset=UTF-8)
@PostMapping("/add")
public Object addUser(String name,String sex){
    User user=new User();
    user.setName(name);
    user.setSex(sex);
    return user;
}
axios({
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
    method: 'post',
    url: "http://localhost:7777/test-request/user/add",
    data: {
        name: that.form.name,
        sex: that.form.sex
        }
    }
    ).then(function (result) {
    alert(result)
});

这种方式不报错,但是后端还是不能够成功的接收到前端发过来的数据,

此时前端的数据格式为:

在这里插入图片描述

请求头也确实为application/x-www-form-urlencoded

在这里插入图片描述

3.4但是在换了一种请求方式之后,改用jquery的ajax之后
 $.ajax({
     type:"post",
     url:"http://localhost:7777/test-request/user/add",
     data:{
         name: that.form.name,
         sex: that.form.sex
     },
     success: function (data) {
         alert(data)
     }
 })

后端成功接收到了数据。

此时查请求头和请求数据格式如下:

在这里插入图片描述

在使用jquery的ajax时我们并没有设置他的请求中 Content-Type,说明它默认为form表单的数据类型

但是请求的表单数据已经变为了键值对类型数据,并不是axios中的那种json格式的数据

3.5 使用axios的qs将数据变为form类型的数据
axios.post("http://localhost:7777/test-request/user/add",
           qs.stringify({name: that.form.name,sex: that.form.sex}),
           {headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}})
    .then(function (result) {
        that.result = result;
        alert(result)
    });

此时后端可成功接收到参数,前端数据格式也变为了form类型的键值对数据格式

3.6 使用jquery的ajax,后端采用@RequestBody注解,使用实体类来进行接收

在3.4中发现ajax默认是使用application/x-www-form-urlencoded; charset=UTF-8来进行接收参数的,所以必须修改Content-Type的类型为application/json

如不修改则报错415,错误信息如下

{"timestamp":"2021-09-10T06:19:11.814+0000","status":415,"error":"Unsupported Media Type","message":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","path":"/test-request/user/add"}

此时第一想到的一定是去修改请求头中的Content-Type为Application/json

$.ajax({
    type:"post",
    url:"http://localhost:7777/test-request/user/add",
    contentType: 'application/json',
    data:{
        name: that.form.name,
        sex: that.form.sex
    },
    success: function (data) {
        alert(data)
    }
})

再次发起请求,发现报错400,错误信息如下:

{"timestamp":"2021-09-10T06:24:09.435+0000","status":400,"error":"Bad Request","message":"JSON parse error: Unrecognized token 'name': was expecting 'null', 'true', 'false' or NaN; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'name': was expecting 'null', 'true', 'false' or NaN\n at [Source: (PushbackInputStream); line: 1, column: 6]","path":"/test-request/user/add"}

此时的请求数据格式为:

在这里插入图片描述

数据变为了这种被编码过的并且是&拼接起来的数据,并不是合理的json数据

解决方案:将数据使用JSON.stringify()函数将数据转换为json字符串

var searchData={name: that.form.name,sex: that.form.sex};
$.ajax({
    type:"post",
    url:"http://localhost:7777/test-request/user/add",
    contentType: 'application/json',
    data:JSON.stringify(searchData),
    success: function (data) {
        alert(data)
    }
})

此时得到后端正确的响应信息,成功。此时的数据格式为:

在这里插入图片描述

三、总结

不带@RequestBod实体类接收带@RequestBod注解的实体类参数接收
ajax,参数进行JSON.stringify()处理,不添加contentType请求头,使用默认的无法接收数据,不报错无法接收数据,不报错无法接收数据,不报错
ajax,参数进行JSON.stringify()处理,添加contentType请求头为’application/json’无法接收数据,不报错可以正常接收无法接收数据,不报错
ajax,参数不进行JSON.stringify()处理,不添加contentType请求头,使用默认的可以正常接收报错415可以正常接收
ajax,参数不进行JSON.stringify()处理,添加contentType请求头’application/json’无法接收数据,不报错报错400无法接收数据,不报错

ContentType类型

application/x-www-form-urlencoded,这种格式会对表单数据进行url编码

multipart/form-data, 文件上传时候必须使用这种格式

application/json, post常用的格式,使用此种格式时候必须对数据进行json处理

@RequestBody

一个请求只能有一个该注解

后端@RequestBody注解对应的类在将前端的请求数据(包含请求体)包装为一个实体类,(即:@RequestBody后面的类),会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为)

json字符串中的value的数据类型和实体类中的若不对应,则接收到的参数类型为null

application/json, post常用的格式,使用此种格式时候必须对数据进行json处理

@RequestBody

一个请求只能有一个该注解

后端@RequestBody注解对应的类在将前端的请求数据(包含请求体)包装为一个实体类,(即:@RequestBody后面的类),会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为)

json字符串中的value的数据类型和实体类中的若不对应,则接收到的参数类型为null

  • 23
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个小白QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值