contentType是告诉发送到服务端的数据类型,dataType是接收服务端的数据类型。

简单的数据用默认的application/x-www-form-urlencoded即可,post的方法体中会是a=bc&d=e%2Cf形式。但是这种形式满足不了复杂的json嵌套。

上面的话展开说就是

这种格式的特点就是,name/value 成为一组,每组之间用 & 联接,而 name与value 则是使用 = 连接。如: wwwh.baidu.com/q?key=fdsa&lang=zh 这是get , 而 post 请求则是使用请求体,参数不在 url 中,在请求体中的参数表现形式也是: key=fdsa&lang=zh的形式,这种形式在一般的情况下是没有什么问题的,但是在一些复杂的情况下就有问题了。 如果在ajax 中你要传一个复杂的json 对像,也>就说是对象嵌数组,数组中包括对象,这样你怎么传:

1
2
3
4
5
6
7
{
data: {
a: [{
x: 2
}]
}
}

如上面这个复杂对象,get 和 post 都没有办法进行传送,因为历史的原因,ajax 只支持简单JSON对象(不带嵌套的)。所以在 ajax 中,你指定的 application/x-www-form-urlencoded 就不能传复杂JSON对象。你可以测试一下。
application/json 的类型,把 json 的对像,用JSON.stringify序列化后,然后发送,在服务器端接到然后用 JSON.parse 进行还原就行了,这样就能处理复杂的对象了。

下面的内容可能不准确 因为本文重点在于application/x-www-form-urlencoded vs application/json。我之前不懂误以为是@RequestParam vs @RequestBody。

1.@RequestBody 注解,必须与 contentType 类型application/json配合使用。 把前端接收来的json封装到对象中。

https://blog.csdn.net/a460550542/article/details/103307204
      @RequestBody注解常用来处理POST请求,并且content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。
      在《Spring 实战》中,表明了@RequestBody注解的含义和使用方式:用来解析请求体(可能是POST,PUT,DELETE,GET请求)中Content-Type为application/json类型的请求,利用消息转换器将其转换为对应的java对象。
      当请求中的ContentType分别为一下三种类型时,结果如下:

是否加上注解\ContentType x-www-form-urlencoded form-data application/json
不加@RequestBody注解 能接收 能接收 不能接收
加上@RequestBody注解 不能接收 不能接收 能接收

@RequestBody是读取的流的方式, 在取 body参数时第一个参数取到后把request.getInputStream()关闭,导致后面的@requestBody的对象拿取不到,就会报错。

@RequestBody,它是用来处理前台定义发来的数据Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等。

关于@RequestBody有一篇超长csdn文章https://blog.csdn.net/justry_deng/article/details/80972817

2.@RequestParam 注解,不加貌似也没区别, public String test(@RequestParam Long parentId) vs public String test( Long parentId)
只是加了这个参数parentId就不能空了。除非用RequestParam(required=false)。

3.不加注解接收参数,参数类型可以为简单类型public String test(int parentId) ,也可以为对象类型 public String test(Version version)但是混用?

public String test(int parentId) public String test(Version version) public String test( Map<String, Object> map )
啥也不加 + x-www-form-urlencoded 不行
@RequestParam + x-www-form-urlencoded 不行 不行
@RequestBody + application/json 不行

下面是一个ajax 规定了data类型JSON.stringify(); contentType是application/json

1
2
3
4
5
6
7
8
9
10

$.ajax({

type: "POST",
data: JSON.stringify(task),
contentType: "application/json;charset=UTF-8",
url: "/updateTask",


});

其对应的controller层就是这样的 完美对应上面的第三条。

1
public Response updateTask(@RequestBody Task task) {}

如果想接受多个实体类 用map
@RequestBody Map<String, Version> map
也需要前台发来json
但是map可不可以用@RequestParam呢 不行

application/x-www-form-urlencoded 这种形式是没有办法将复杂的 JSON 组织成键值对形式

https://www.cnblogs.com/htoooth/p/7242217.html

controller里map接收了 怎么转呢?

1
2
3
4
5
6
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

JSON.parseObject(JSON.toJSONString(数据), new TypeReference<对象>() {

});