杂谈query string paramter、form data和request playload
1、query string parameter(不属于请求体的数据)
query string parameter在get请求和在post请求中都是很常见的 ,它们主要的区别如下
1、get请求和post都会出现,唯一的区别就是get请求中的query string parameter会拼接在url后面,造成数据不安全。==可以理解为它属于url中的一部分,但是在在post请求中这部分数据被隐藏起来了==
2、两者对应的content-type的类型是application/x-www-form-urlencoded=>表单格式(默认的),==也可以使用其他的content-type(任意的),因为它属于url==
3、此参数通过@RequestParam接收,也可以不加
2、form data和request playload(请求体中的数据)
form data和request playload都是属于请求体中出现的数据,也就是会出现在==post==(常见)请求体中,所以不存在使用get请求产生。它们是两种不同的数据传递格式。
request playload
在发送post请求的时候,如果content-type字段设置为==application/json、text/plain;charset=UTF-8、text/html;charset=UTF-8==时 (可能还有其他情况,这里没有全部列举出来) 参数会出现在request playload中
如果希望通过Form Data的方式来传递数据,则可以通过原生方法formData()来进行数据组装, 通过formData()组装后的数据就像表单数据一样,变成了键/值对的形式。==且content-type需要设置为multipart/form-data==,此时request playload里面显示如下数据格式,接收数据数据可以使用一个String 字符串接收,不能加@requestparam,因为属于请求体的数据。其中,WebKitFormBoundaryAIpmgzV8Ohi99ImM
为浏览器随机生成的boundary
,作为分隔参数,作用等同于&
。根据Boundary字符串分割表单的键值对
组装之前的content-type:application/json
组装值后的content-type:Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryjVzwQ46gEXF5Cbrx
------WebKitFormBoundaryjVzwQ46gEXF5Cbrx
Content-Disposition: form-data; name="jsondata" 传递的json字符串变成了from-data格式 K:V=》jsondata:json字符串
[{"medId":101000458,"sendNumTemp":12},{"medId":101000216,"sendNumTemp":5,"sendNumTempMin":6},{"medId":101001922,"sendNumTemp":10,"sendNumTempMin":8},{"medId":101000452,"sendNumTemp":8,"sendNumTempMin":6}]
------WebKitFormBoundaryjVzwQ46gEXF5Cbrx--
- 首部属性contentType可以改变请求的==数据提交方式==(举例):==application/json(payload),application/x-www-form-urlencoded(formData)==
- 使用formData()可以使==payload提交表单数据:multipart/form-data==
from data(表单)
from-data传递数据时,==content-type为:Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW==或者为 :==application/x-www-form-urlencoded(这是浏览器默认的,且为表单格式:from-data)==具体原因如下:
其一、当发起一次POST请求时,==若未指定content-type,则默认content-type为application/x-www-form-urlencoded==。即参数会以Form Data的形式进行传递,不会显式出现在请求url中。
其二、通过formData()组装表单数据,或者指定使用==multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW==
Form Data,其实就是Request Payload当中的特例,主要是指由==浏览器API生成的带有表单数据的请求体数据==。总之就是使用from-data格式传递数据时,有两种对应的content-type,并且是表单数据,键值对形式,使用分隔符
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="kj"
4
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="m"
46
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Type: application/x-www-form-urlencoded
Content-Length: 216
medId=101000458%2C&sendNumTemp=12&medId=101000216%2C&sendNumTemp=5%2C&sendNumTempMin=6&%7B=&%22medId%22=101001922%2C&%22sendNumTemp%22=10%2C&%22sendNumTempMin%22=8&medId=101000452%2C&sendNumTemp=8%2C&sendNumTempMin=6
Form Data 和 Request Payload 区别
一个提交表单形式,一个提交非表单(比如JSON)格式(不能说全部都是这样,因为我也完全没懂,懂了99%)
3、总结:
常见传递形式
1.当我们传递fromdata形式的时候,Content-Type
自动转为xxx-form-xxx
的形式。当为对象的时候,content-type自动转化为xxx/json
。
2.fromdata的时候以key1=val1&key2=val2
的形式体现,对象以JSON字符串形式体现。
后端取不到值?
无论何种形式传递,后端解析表单信息的时候,会考虑Content-Type
。如果是JSON字符串的话,后端解析payload的内容时候,肯定要去解析JSON啦。如果是key1=value1&key2=value2
的形式,则需要去分割字符串(可以使用map,list,或者常见数据类型接收,视情况而定)。
当然这些事情一般后端使用的框架会去处理,但是框架给后端提供取值接口有可能是不同的,所以前端的小伙伴在处理请求问题时,一定要跟后端小伙伴商量好(建议全栈,没那么多破事),是用JSON
还是FormData
哈。
前后端命名尽量一致,可以减少参数映射的很多坑
再谈@RequestBody与@RequestParam
@RequestBody:接收content-type为application/json格式的数据,也就是请求体数据传输格式为Request Payload的数据,主要是针对json格式字符串,可以接收实体类,map,list,list<map>
的数据类型,简单类型完全没必要,因为get更适合简单的,也不符合开发规范。使用它时,对参数命名没有那么多规范,但是我们的命名也应该尽量符合开发规范。并且要注意requried属性
@RequestParam:接收content-type为xxx-from-xxx的数据,也就是在请求体数据传输格式form-data的数据,以及拼接在url中的数据(string query paramter),可以接收简单类型,对象类型(实体类,map,list,list<map>
),但是此方法对参数映射要求更加严格。接收k-v形式的数据可以不要求写这个注解,但是前后端参数名一定要相同。否则就要加上该注解,但是使用该注解时一定要注意它的三个属性,并且小心使用,避免出现坑。