application/json与application/x-www-form-urlencoded详解

1.1 问题再现

今天写项目的时候,前台发送数据到后端。前台的数据是发送了,但是后端收不到数据,后端我用@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-urlencodedapplication/json的区别

说明:这两个都是发送请求的格式说明

1.1.1 application/x-www-form-urlencoded

Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型。 下边是说明:application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。 multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。 text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
补充
formenctype属性为编码方式,常用有两种:application/x-www-form-urlencodedmultipart/form-data,默认为application/x-www-form-urlencoded。 当actionget时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串appendurl后面,用?分割,加载这个新的url。 当actionpost时候,浏览器把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)。

1.1.2 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

1.2 总结

ps:经过本人的试验总结,终于发现了一些东西,就是,当前台传递的参数,在后台不能由一个类全部接受的时候,就用application/x-www-form-urlencoded
例如,我们在初次打开页面,且页面需要分页的功能的时候,后台接受代码如下。此时就有很多的参数,并且,如果此时用application/json的话,接受page就必须时候RequestBody,于是问题又来了,springmvc中如果使用了RequestBody,那么就不能有其他的不能有类接受的单个参数,于是下面的代码中的时间接受就为null。显然这用情况更适合使用application/x-www-form-urlencoded:发送的数据格式为键值对。而application/jsonjson字符串。

 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){
                }
            });

你可能感兴趣的:(Java,json,java,ajax,RequestBody)