前言
HTTP 通信的 7 种方式
在 HTTP 通信中主要分为 GET 和 POST。如 PUT,DELETE 是类 POST 的传输方式,与 POST 没有实质区别。OPTION 是查看服务器支持的请求方法。HEAD 是测试服务器的该资源情况,不返回实体的主体部分。TRACE 请求可以获取回服务器接收到的该请求的原始报文,从而判断路径中的代理和防火墙是否对该条请求进行修改。
HTTP 请求报文发送格式不因请求方式不同而改变
- HTTP 报文格式如下
< 请求方法 > < 请求路径 > < 协议版本 >
< 请求头 >
< 主体 body>
- 无论用任何请求方法,都可以发送这样的请求报文,报文结构是 HTTP 的协议规范,请求方法只是告诉服务器如何来看待这条请求。因为在有些文章中会提到 GET 请求不能传 body 数据,而真实的情况是有些服务端框架接收到 GET 请求后会自动将 GET 请求的 body 部分丢弃,所以大家要注意。所以为了规范,大家在使用 GET 请求时还是不要将请求数据放在 body 中。
何时用 GET 请求
为了规范,使用 GET 请求时就不要在主体 body 中放数据了,避免不必要的错误。所以请求中的数据是放在 URL 上的。
- 浏览器网址栏和页面跳转。
- 为了获取信息且不需要传大量条件信息的接口。
例如用 GET 做登录请求
GET /online/test/?name=haha& password=miaomiao HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: 14a1347a-c540-48f0-9d49-6299f86c3a73
何时用 POST 请求
post 请求可以在 body 中传送大量信息
以上传 name=haha,password=miaomiao 为例,查看不同 body 数据格式
form-data(表单,可以传文件)
POST /online/test/? HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
cache-control: no-cache
Postman-Token: c6e21725-caec-4a40-841c-7b92f87f6999
Content-Disposition: form-data; name="name"
haha
Content-Disposition: form-data; name="password"
miaomiao
------WebKitFormBoundary7MA4YWxkTrZu0gW--
若在表单中附加一张图片
POST /online/test/? HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
cache-control: no-cache
Postman-Token: 437207ba-e007-4de8-bbcd-bdc88db6e445
Content-Disposition: form-data; name="name"
haha
Content-Disposition: form-data; name="password"
miaomiao
Content-Disposition: form-data; name="profile"; filename="C:\Users\Think\Pictures\profile.jpg
------WebKitFormBoundary7MA4YWxkTrZu0gW--
- 其中表单的每一项都有 Content-Disposition 描述。
- ——WebKitFormBoundary7MA4YWxkTrZu0gW– 是随机生成的分隔标记
x-www-form-urlencoded(也是表单,但不可以传文件)
POST /online/test/? HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: 35566466-0568-4731-9c1c-6eda7dfca105
name=hahapassword=miaomiaoundefined=undefined
- 因为不用传文件,所以不用单独描述,将表单信息拼凑在一起就可以了。
- application/x-www-form-urlencoded:窗体数据被编码为名称 / 值对。这是标准的编码格式。
- multipart/form-data:窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
raw(text,json,xml…)(其它文本格式)
以 json 格式为例
POST /online/test/? HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: application/json
cache-control: no-cache
Postman-Token: 06a9f071-4424-428a-b17b-9b4fe6f209a2
{
"name":"haha",
"password":"miaomiao"
}------WebKitFormBoundary7MA4YWxkTrZu0gW--
binary(二进制)
用作传输文件,包括前面的 form-data 上传文件,文件都是以一定的编码方式写在 body 中的,在服务器端获取该请求的输入流后,即可按行接收流中的数据信息。
在 Spring Boot 中接口的接收数据总结
URL 接收
GET 参数列表对于数字基本类型和包装类型都可接收,但是若前端并没传这个数字,那么包装类型可以在代码里判空,异常处理就好,但是基本类型是不能判空的,所以对于数字首选包装类型。
@RequestMapping(value = "/",method = RequestMethod.GET)
@ResponseBody
private ResInfo test(String name,String password){return new ResInfo(200,"登录成功:"+name+" "+password);
}
PostMan 接收
{
"code": 200,
"msg": "登录成功:haha miaomiao"
}
表单数据
两种表单的请求 Java 接口都可以这样写。
@RequestMapping(value = "/",method = RequestMethod.POST)
@ResponseBody
private ResInfo test(String name,String password){return new ResInfo(200,"登录成功:"+name+" "+password);
}
若表单中要上传文件,则文件项该用注解写名称,参数名都可用 @RequestParam 替代。只有 form-data 可以接收文件。
@RequestMapping(value = "/",method = RequestMethod.POST)
@ResponseBody
private ResInfo test(String name,String password,@RequestParam("profile") MultipartFile multipartFile){String fileName = multipartFile.getOriginalFilename();
return new ResInfo(200,"登录成功:"+name+""+password+" 文件名:"+fileName);
}
Postman 响应
{
"code": 200,
"msg": "登录成功:haha miaomiao 文件名:profile.jpg"
}
接收 json 对象
class User {
public String name;
public String password;
public User() {}
// 若重写了构造方法,一定要写上空构造方法,否则 spring 不能 new 新对象以接收 json
public User(String name, String password) {
this.name = name;
this.password = password;
}
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseBody
private ResInfo test(@RequestBody User user) {return new ResInfo(200, "登录成功:" + user.name + " " + user.password);
}
Postman 响应
{
"code": 200,
"msg": "登录成功:haha miaomiao"
}
json 对象和单个值混合接收
思想:把 json 对象放在 body 中,把单个值放在 url 参数列表中,所以构造请求时 url 和 body 两部分都要构造。
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseBody
private ResInfo test(@RequestBody User user, String msg) {return new ResInfo(200, "登录成功:" + user.name + "" + user.password +"msg:" + msg);
}
Postman 响应
{
"code": 200,
"msg": "登录成功:haha miaomiaomsg:hello, my name is msg !"
}
至此完成了从 HTTP 构造到 spring 对接口解析的总结与梳理,欢迎大家指正。