application/x-www-form-urlencoded请求出现400错误

最近实现一个分页的功能,因为分页所以参数多且杂乱,一个实体类是接受不完的,于是就用了application/x-www-form-urlencoded这种请求方式,而不是application/json,两者的区别以及在什么情况下使用请看博客,有详细的说明:https://blog.csdn.net/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
        }

完美解决问题

果真是一步一个坑

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值