今天写项目的时候,前台发送数据到后端。前台的数据是发送了,但是后端收不到数据,后端我用@RequestBody
,一直为null
,然后去掉该注解,还是为null
,再后来索性,只用一个IntegerNumber
去接收,然而还是null
…。最后请教了公司的程大神,才将bug
解决掉了。
错误代码如下:
getUserList:function(){
$.ajax({
type:"post",
url:this.api.userListUrl,
dateType:"json",
contentType : 'application/json',
data:this.queryParam,
success:function(result){
app.userList=result.data.rows;
app.pagination.total=result.data.total;
},
error:function(result){
}
});
}
Controller
代码:注意,以下代码其实没什么问题,但是接受参数的时候,自定义类前面的用@RequestBody
才能接收,但问题就是SpringMVC
中,如果用了@RequestBody
,就不能再接受单个的参数了,如 Integer i
。
@RequestMapping("/user/page.do")
@ResponseBody
public ApiResult userPage(
@RequestBody MyPage page,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime
){
System.out.println(page.getPageNumber());
System.out.println(page.getPageSize());
System.out.println(startTime);
System.out.println(endTime);
ApiResult apiResult = new ApiResult();
apiResult.setData(userService.userPage(page));
return apiResult;
}
改进,将ajax
发送请求的application/json
改为application/x-www-form-urlencoded
,然后Controller
里的MyPage
,就不用添加@RequesyBody
了,于是既可以接受自定义的对象参数,又可以接受单个的参数。完美解决问题
application/x-www-form-urlencoded
下面我们来看看application/x-www-form-urlencoded
与application/json
的区别
说明:这两个都是发送请求的格式说明
application/x-www-form-urlencoded
在Form
元素的语法中,EncType
表明提交数据的格式 用 Enctype
属性指定将数据回发到服务器时浏览器使用的编码类型。 下边是说明:application/x-www-form-urlencoded
: 窗体数据被编码为名称/值对。这是标准的编码格式。 multipart/form-data
: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。 text/plain
: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
补充
form
的enctype
属性为编码方式,常用有两种:application/x-www-form-urlencoded
和multipart/form-data
,默认为application/x-www-form-urlencoded
。 当action
为get
时候,浏览器用x-www-form-urlencoded
的编码方式把form
数据转换成一个字串(name1=value1&name2=value2…)
,然后把这个字串append
到url
后面,用?
分割,加载这个新的url
。 当action
为post
时候,浏览器把form
数据封装到http body
中,然后发送到server
。 如果没有type=file
的控件,用默认的application/x-www-form-urlencoded
就可以了。 但是如果有type=file
的话,就要用到multipart/form-data
了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition
(form-data
或者file
),Content-Type
(默认为text/plain
),name
(控件name)
等信息,并加上分割符(boundary
)。
application/json
有的时候发现 ajax
请求中 content-type:application/json
,这样也能在后台接受前台提交的数据,其实这个时候前端提交的数据是 json
格式的字符串,后端要用@requestbody
注解来接收
推荐链接:https://www.cnblogs.com/qlhMeiMei/p/6846392.html
content-type:application/json
的数据格式:json
字符串
application/x-www-form-urlencoded
的数据格式:键值对:key-value
发现服务器的接口接收的数据的格式是form
表单形式,而Angular
的$http
服务发送的post
请求默认是json
数据格式所以数据接收不到
推荐连接:https://blog.csdn.net/leftfist/article/details/79053389
https://blog.csdn.net/wopelo/article/details/78783442
ps
:经过本人的试验总结,终于发现了一些东西,就是,当前台传递的参数,在后台不能由一个类全部接受的时候,就用application/x-www-form-urlencoded
。
例如,我们在初次打开页面,且页面需要分页的功能的时候,后台接受代码如下。此时就有很多的参数,并且,如果此时用application/json
的话,接受page
就必须时候RequestBody
,于是问题又来了,springmvc
中如果使用了RequestBody
,那么就不能有其他的不能有类接受的单个参数,于是下面的代码中的时间接受就为null
。显然这用情况更适合使用application/x-www-form-urlencoded
:发送的数据格式为键值对。而application/json
为json
字符串。
public ApiResult receive(Page page, ReportReceive filter,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime) {
return new ApiResult(receiveService.page(page, filter, startTime, endTime));
}
如果前端发送给后台的数据只是一个对象(使用场景:如注册,保存空户,修改信息),那么我们就大课放心的使用application/json
来处理数据,即:只需要在后台接受的时候添加@RequestBody
即可
@RequestMapping("/reply/save.do")
@ResponseBody
public ApiResult replySave(@RequestBody ReportReceive receive) {
receive.setReplyTime(new Date());
if (receive.getReplyStatus() == 1) {
reportService.updateReplyCount(receive.getReportId());
}
return new ApiResult(receiveService.updateSelective(receive));
}
注:axios
默认使用的是application/json
格式,所以大家在向后台发送数据的时候,要小心喽。所以呢如果大家直接用$.ajax
来提交post
请求的话,最好好设置响应头contentType
的值。
$.ajax({
type:"post",
url:this.api.treeListUrl,
dateType:"json",
contentType : 'application/json',
success:function(result){
app.options=result.data;
console.log(app.treeList);
},
error:function(result){
}
});