一篇解决springMVC前后端参数传递问题

一、先来看一个常见的异常

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

 前端代码:

  $.ajax({
        type:"post",
        url:"/test",
        data:JSON.stringify({id:1,name:"小明",gender:true}),
        success:function (result) {
            console.log(result);
        }
    });

后端代码:

    @ResponseBody
    @RequestMapping("/test")
    public Object testJson(@RequestBody User user){
        System.out.println(user);
        return user;
    }

前后端用json字符串做数据交互。一运行就报了上面的异常了。

先说一下解决方法:

ajax中加上一个键值对:contentType:"application/json" 就行了。

原因:前端用 JSON.stringify({id:1,name:"小明",gender:true}) 将一个js对象转换成了json字符串,后端通过@RequestBody注解表示要解析json字符串(相当于fastJson来解析json字符串)并赋值给User对象,我们发送的是http请求,后端在解析请求参数时并不是直接解析内容,若是post请求的话,他会先检查HTTP请求的Content-type属性值,根据这个属性值来判断请求体中的数据格式。前端我们发的ajax请求默认的contentType属性值为:application/x-www-form-urlencoded;charset=UTF-8,这个contentType表示的数据格式是键值对格式。所以我后端需要json格式的数据,你给我传递个键值对格式,我肯定说不支持啊。

所以我们用contentType:"application/json"来改变http请求,表示我发送的数据是json格式的,后端就可以识别了呗。

二、深入研究一下,从根本上解决这个参数传递问题

1、请求的数据格式的区别

  1. 因为content-Type是用来表示请求体的类型的,默认值为默认为application/x-www-form-urlencoded; charset=UTF-8,这个称为MIME类型。get请求没有请求体,所以就没有content-Type属性;post请求有请求体,所以就会有content-Type属性。
  2. form表单的默认MIME类型也是application/x-www-form-urlencoded,即enctype="application/x-www-form-urlencoded",如果是文件上传则enctype="multipart/form-data"
  3. 键值对格式:name=www&url=www&checked=true&pId=6

              常见场景

                  1)form表单默认MIME类型时

                  2)serialize()方法

                  3)ajax中的js对象(根据ajax文档显示,最终js对象在发送时会被转化成键值对格式)

                  4)get请求

                  5)FormData对象

     4.Json格式:{"name":"www","url":"www","checked":true,"pId":6}

       data:JSON.stringify({name:name,url:url,checked:checked,pId:pId}), //将js对象转换成json字符串格式

       contentType:"application/json" //设置请求的MIME类型为application/json格式,即json格式

     5.请求体的区别:Form data 和Request Payload

         1、当post请求的content-Type属性的值为application/x-www-form-urlencoded; charset=UTF-8时,数据封装在Form data中,键值对格式

         2、当post请求的content-Type属性的值为application/json或text/plain时,数据封装在Request Payload中,json格式

2、获取请求参数(总结一下)

      键值对格式

           1、只要保证请求的参数名和处理器方法的形参名称一致,自动绑定成功。

           2、获取单个请求参数

                     1)@RequestParam注解:获取一个请求参数,并赋值给一个形参

属性

@RequestParam(value="password",required=false,defaultValue="0") int password

required:设置属性是否为必须的,默认为true。可以设置其值为false,即当没有该属性时也不会报错。

defaultValue:当required=false时使用,设置请求参数的默认值,不能单独使用。

                     2)@PathVariable 注解:针对rest风格的url,可以将url的占位符参数,绑定到处理器方法的入参处

<a href="/springmvc/testPathvariable/12/tom">testPathvariable</a>

@RequestMapping("/testPathvariable/{id}/{name}")

public String testPathVariable(@PathVariable("id") Integer id,@PathVariable("name") String name) {

    System.out.println(id);

    return "success";

}

                     3)@RequestHeader注解:获取请求头中的参数。

如:@RequestHeader(value="Accept-Language") 这是获取请求头中Accept-Language属性的值。

                     4)@CookieValue注解:获取cookie中某个键值对的值。

@CookieValue("JSESSIONID")获取JSESSIONID属性的值。

            3、获取多个请求参数

     使用POJO(普通的Java类)作为参数:按照请求参数名(name属性名)和POJO属性名进行自动匹配,自动通过setter方法为该对象填充属性值,且支持级联属性

       json格式

     1.@RequestBody User user(推荐)

             用实体类接收,json的key要和实体类属性一致。

     2.@RequestBody Map<String,Object> map(次推荐)

             用map接收,json的key要和map的key一致

     3.@RequestBody String str (这样是将整个json字符串赋值给str,不推荐)

             用字符串接收,然后在自己解析json字符串

ok,结束,吃饭去。

发布了10 篇原创文章 · 获赞 1 · 访问量 724

猜你喜欢

转载自blog.csdn.net/qq_40925189/article/details/103943463