最近实现一个分页的功能,因为分页所以参数多且杂乱,一个实体类是接受不完的,于是就用了application/x-www-form-urlencoded这种请求方式,而不是application/json,两者的区别以及在什么情况下使用请看博客,有详细的说明:https://blog.youkuaiyun.com/java_xxxx/article/details/81205315
然后问题就出现了,就是我发送请求一直给我报400的错误,我就纳闷了,一直调试,一直调试,结果发现了问题,如图所示,我后台封装的有初始页的大下,与页码,当点击提交的时候,会将这些参数一直快提交,但是问题出现了,当我指点击提交而不选择日期的时候,完全没问题,前台发送,后端接受到参数。但是当点选择过日期后,就一直报400。
原因分析:400,那就是请求头或者数据格式不正确,在排除了请求头没问题后,那就是数据格式的原因了,但是这个是表单提交,没问题啊,后来干脆把发送的数据JSON.stringify(参数);将它转为字符串,结果,前台没报错了,后台接受得到的参数全部null。然后再象会不会是日期的格式原因,我用的是elementUI的时间控件。代码如下:大家不要误解,这里的type:date是显示类型,实际类型还是字符串,有兴趣的朋友可以去看elementUI的官方文档(http://element-cn.eleme.io/#/zh-CN/component/date-picker),但是不知道是什么原因导致该类型无法正确的被解析,于是在发送ajax到后台的过程中,就出现了问题
html
<el-date-picker
v-model="queryParam.startTime"
type="date"
placeholder="选择日期">
</el-date-picker>
解决办法:在控件里指定日期的格式,然后将日期加上一个字符串,就变为了字符串类型了
代码如下
html
<el-date-picker
v-model="queryParam.startTime"
type="date"
@change="dataChange"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
js:注意,该方法还有另外一个好处,那就是我们在实现时间查询的时候,一般都是开始时间和截止时间,如果用的是ssm+mysql的话,它查询不到当天的即(2018-08-06-2018-08-08),它查询不到08-08这天的数据,符合一般的左开右闭原则。但是很苦恼,于是我们在这里直接将时间定义为年月日,在js里将开始时间设为0,结束时间加上23h59m59s。一举两得。
dataChange:function () { // 时间查询
// 由于我用的是elementUI的时间控件,他的数据格式可能不是字符格式的
if(this.queryParam.startTime!='' && this.queryParam.startTime.length != 19){
this.queryParam.startTime+=' 00:00:00';
}
if(this.queryParam.endTime!='' && this.queryParam.endTime.length != 19){
this.queryParam.endTime+=' 23:59:59';
}
this.getUserList();
}
发送请求
$.ajax({
type:"post",
url:this.api.page,
dateType:"json",
contentType : 'application/x-www-form-urlencoded',
data:this.queryParam,
success:function(result){
}
});
参数queryParam
var _queryParam={ // 分页条件查询
pageSize:2, // 每页显示条数默认值
pageNumber:1, // 当前页码默认值
startTime:"", // 按创建时间查询
endTime:""
}
controller代码
@RequestMapping("/ptUser/page.do")
@ResponseBody
public ApiResult page(MyPage page,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime){
ApiResult apiResult = new ApiResult();
System.out.println("页面大小"+page.getPageSize());
System.out.println("页码"+page.getPageNumber());
System.out.println("开始时间"+startTime);
System.out.println("结束时间"+endTime);
return apiResult;
}
////////////////////////////////////////////////////////////////////////////////////////
上面的例子是用的原始的ajax请求方式来发送的请求,接下来我们用axios来发送请求,因为是axios,有点坑,如果只是改变请求头为表单提交,那么后台将得不到任何数据,它吧所有的请求方式都会转换成application/json这种格式,它默认的也是这种格式,下面我们就来解决了它
axios.post(this.api.page, this.transformRequest(this.queryParam), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function (response) {
//console.log(response);
})
.catch(function (error) {
// console.log(error);
});
因为我们这里是用表单方式提交的,所以参数的形式为键值对方式得用=和&,但是axious是用的application/json,所以,我们要改变参数的封装格式
transformRequest: function (data) {
var ret = '';
for (var it in data) {
if(data[it] != null && data[it] !== ''){
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
}
return ret
}
完美解决问题
果真是一步一个坑