@Component
public class WebConfig implements WebMvcConfigurer {
/**
* springboot 无法直接访问静态资源,需要放开资源访问路径。
* 添加静态资源文件,外部可以直接访问地址
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/templates/");
}
}
@RequestMapping("/user")
@RestController
public class UserController {
}
@PostMapping("/add")
public Object addUser(@RequestBody User user){
return user;
}
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
@PostMapping("/add")
public Object addUser(User user){
return user;
}
接口响应结果:
可以看出此时虽然不会报错,但后端无法解析前端传来的json数据,返回的数据均为null
@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的值,说明后端还是无法解析此时的参数
@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
$.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格式的数据
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.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