🚋 请求体
# 添加请求体
ForestRequest 对象提供的添加/修改请求体数据项的方法
addBody(String bodyString)
添加字符串Body数据项
request.addBody("xxxx") // 添加字符串请求体 xxxx
.addBody("yyyy"); // 添加字符串请求体 yyyy
// 最终请求体为:
// xxxxyyyy
2
3
4
addBody(String name, Object value)
添加键值对形式的Body数据项
request.addBody("a", 1) // 添加请求体数据项,键值对: a, 1
.addBody("b", 2); // 添加请求体数据项,键值对: b, 2
2
现在 ForestRequest 对象中有了两个请求体数据项,风别是键值对<a, 1>
和 <b, 2>
至于它们最终以什么数据格式发送,取决于请求头中的 Content-Type
的值
# 添加对象请求体
addBody(Object obj)
添加对象形式的Body数据项
- 参数
obj
: 作为请求体数据的任意类型对象
// 添加自定义类对象
MyUserInfo userInfo = new MyUserInfo();
userInfo.setName("foo");
request.addBody(userInfo);
// 添加Map对象
Map<String, Object> map = new HashMap<>();
map.put("name", "foo");
map.put("value", "bar");
request.addBody(map);
2
3
4
5
6
7
8
9
10
# 添加延迟请求体
延迟请求体参数 (也称作 Lambda 请求体参数),在您需要不马上求值的情况使用。
有很多情况,Body的参数值不能马上得出,而是在请求发送前的那一刻(所有请求参数都到位时)才能得出,典型的例子就是加签验证的场景(在请求体参数中添加一个参数token,而token的值是对整个body(除token之外所有参数)做加密的结果)
addBody(String name, Lazy lazyValue)
添加Lazy类型的请求体参数
- 参数
lazyValue
: 延迟求值的请求体参数值(即 Lambda)
request.addBody("name", req -> {
// req 为请求对象
// 返回值将作为参数值添加到请求体中
return "";
});
2
3
4
5
在 Lambda 代码块中可以调用req.body().encode()
可以立即序列化整个请求体的数据
但会自动排除 Lambda 所对应的 Body 项(即 token 字段),而不用担心会造成死循环
request.addBody("a", 1) // 添加 Query 参数 a=1
.addBody("b", 2) // 添加 Query 参数 b=2
.addBody("c", 3) // 添加 Query 参数 c=3
.addBody("token", req -> Base64.encode(req.body().encode())); // 添加延迟参数
// 最终请求体数据为
// a=1&b=2&c=3&token=YT0xJmI9MiZjPTM=
2
3
4
5
6
# 请求体类型
HTTP 请求体有多种不同的类型,如 JSON、XML、文件等等。他们通常是通过Content-Type
头来指定类型的,比如 JSON 数据格式的Content-Type
是application/json
。
不过这是在符合HTTP标准的情况下的请求头和请求体的定义,在某些非标准的情况下,往往也会出现Content-Type
和实际请求体数据类型不一致的情况。
# 表单数据
在调用 addBody 方法前,需要先指定 Content-Type 为 application/x-www-form-urlencoded
插入键值对形式的表单数据
// 创建表格格式请求体
// 按键值对形式添加请求体数据项
Forest.post("/")
.contentFormUrlEncoded() // 指定请求体为表单格式
.addBody("name", "foo") // 添加Body键值对: name, foo
.addBody("value", "bar"); // 添加Body键值对: value, bar
// 最终请求体数据为
// name=foo&value=bar
2
3
4
5
6
7
8
插入Map形式的表单数据
// 构建Map对象
Map<String, Object> map = new HashMap();
map.put("name", "foo");
map.put("value" "bar");
// 创建表格格式请求体
// 按Map形式添加请求体数据项
Forest.post("/")
.contentFormUrlEncoded() // 指定请求体为表单格式
.addBody(map); // 添加Map对象到请求体中
// 最终请求体数据为
// name=foo&value=bar
2
3
4
5
6
7
8
9
10
11
插入自定义对象形式的表单数据
// 用自定义的 MyUserInfo 类对象
MyUserInfo user = new MyUserInfo();
user.setUsername("Jack");
user.setAge(20);
// 创建表格格式请求体
// 按自定义对象形式添加请求体数据项
Forest.post("/")
.contentFormUrlEncoded() // 指定请求体为表单格式
.addBody(user); // 添加自定义类对象到请求体中
// 最终请求体数据为
// username=Jack&age=20
2
3
4
5
6
7
8
9
10
11
混合使用多种形式
// 构建Map对象
Map<String, Object> map = new HashMap();
map.put("name", "foo");
map.put("value" "bar");
// 构建自定义类对象
MyUserInfo user = new MyUserInfo();
user.setUsername("Jack");
user.setAge(20);
// 创建表格格式请求体
// 按自定义对象形式添加请求体数据项
Forest.post("/")
.contentFormUrlEncoded() // 指定请求体为表单格式
.addBody("a", 1) // 添加Body键值对: a, 1
.addBody("b", 2) // 添加Body键值对: b, 2
.addBody(map) // 添加Map对象到请求体中
.addBody(user); // 添加自定义类对象到请求体中
// 最终请求体数据为
// a=1&b=2&name=foo&value=bar&username=Jack&age=20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# JSON数据
在调用 addBody 方法前,需要先指定 Content-Type 为 application/json
或其他json
字符串结尾的 Content-Type 值
插入键值对形式的JSON数据
// 创建JSON格式请求体
// 按键值对形式添加请求体数据项
Forest.post("/")
.contentTypeJson() // 指定请求体为JSON格式
.addBody("name", "foo") // 添加Body键值对: name, foo
.addBody("value", "bar"); // 添加Body键值对: value, bar
// 最终请求体数据为
// {"name": "foo", "value": "bar"}
2
3
4
5
6
7
8
插入Map或List形式的表单数据
// 构建Map对象
Map<String, Object> map = new HashMap();
map.put("name", "foo");
map.put("value" "bar");
// 创建JSON格式请求体
// 按Map形式添加请求体数据项
Forest.post("/")
.contentTypeJson() // 指定请求体为JSON格式
.addBody(map); // 添加Map对象到请求体中
// 最终请求体数据为
// {"name": "foo", "value": "bar"}
// 构建List对象
List<Integer> list = new ArrayList();
value.add(1);
value.add(2);
value.add(3);
// 创建JSON格式请求体
// 按Map形式添加请求体数据项
Forest.post("/")
.contentTypeJson() // 指定请求体为JSON格式
.addBody(list); // 添加List对象到请求体中
// 最终请求体数据为
// [1, 2, 3]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
插入自定义对象形式的表单数据
// 构建自定义类对象
MyUserInfo user = new MyUserInfo();
user.setUsername("Jack");
user.setAge(20);
// 创建JSON格式请求体
// 按自定义对象形式添加请求体数据项
Forest.post("/")
.contentTypeJson() // 指定请求体为JSON格式
.addBody(user); // 添加自定义类对象到请求体中
// 最终请求体数据为
// {"username": "Jack", "age", 20}
2
3
4
5
6
7
8
9
10
11
JSON数据请求体,同样可以混合多种形式添加
// 构建Map对象
Map<String, Object> map = new HashMap();
map.put("name", "foo");
map.put("value" "bar");
// 构建自定义类对象
MyUserInfo user = new MyUserInfo();
user.setUsername("Jack");
user.setAge(20);
// 创建JSON格式请求体
// 按自定义对象形式添加请求体数据项
Forest.post("/")
.contentTypeJson() // 指定请求体为JSON格式
.addBody("a", 1) // 添加Body键值对: a, 1
.addBody("b", 2) // 添加Body键值对: b, 2
.addBody(map) // 添加Map对象到请求体中
.addBody(user); // 添加自定义类对象到请求体中
// 最终请求体数据为
// {"a": 1, "b", 2, "name": "foo": "value", "bar": "username": "Jack&age": 20}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
最后,介绍一种最简单直白的添加JSON请求体的办法
// 创建JSON格式请求体
// 按字符串形式添加请求体数据项
Forest.post("/")
// 指定请求体为JSON格式
.contentTypeJson()
// 插入JSON字符串到请求体中
.addBody("{\"name\": \"foo\", \"value\": \"bar\"}")
// 最终请求体数据为
// {"name": "foo", "value": "bar"}
2
3
4
5
6
7
8
9
# XML数据
在调用 addBody 方法前,需要先指定 Content-Type 为 application/xml
或其他xml
字符串结尾的 Content-Type 值
Forest仅支持用JAXB配合自定义类对象的形式添加XML格式请求体
@XmlRootElement(name = "user")
public MyUserInfo {
private String usrname;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在Body中插入 MyUserInfo 对象
// 构建自定义类对象
MyUserInfo user = new MyUserInfo();
user.setUsername("foo");
user.setPassword("bar");
// 创建XML格式请求体
// 按自定义对象形式添加请求体数据项
Forest.post("/")
.contentTypeXml() // 指定请求体为JSON格式
.addBody(user); // 添加自定义类对象到请求体中
// 最终请求体数据为
// <user><username>foo</username><password>bar</password></user>
2
3
4
5
6
7
8
9
10
11
同样,XML格式请求体也可以用字符串形式直接插入
// 创建JSON格式请求体
// 按字符串形式添加请求体数据项
Forest.post("/")
// 指定请求体为JSON格式
.contentTypeJson()
// 插入XML字符串到请求体中
.addBody("<user><username>foo</username><password>bar</password></user>")
// 最终请求体数据为
// <user><username>foo</username><password>bar</password></user>
2
3
4
5
6
7
8
9
# 文件
在调用 addBody 方法前,需要先指定 Content-Type 为 multipart/form-data
然后调用 addFile 方法,添加文件数据
添加 File
对象
addFile(String name, File file, String filename, String contentType)
添加文件 (接受File对象)
参数
name
: 参数名称参数
file
: 文件, File 类型对象参数
filename
: 文件名, 期望上传的文件数据在服务端保存的文件名参数
contentType
: 文件数据的 Content-Type
addFile(String name, File file, String filename)
添加文件 (接受File对象)
addFile(String name, File file)
添加文件 (接受File对象)
// 构建File对象
File file = new File(path);
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加File对象
.addFile("file", file);
2
3
4
5
6
7
添加输入流对象
addFile(String name, InputStream inputStream, String filename, String contentType)
添加文件 (接受输入流)
参数
name
: 参数名称参数
inputStream
: 文件输入流对象参数
filename
: 文件名, 期望上传的文件数据在服务端保存的文件名参数
contentType
: 文件数据的 Content-Type
addFile(String name, InputStream inputStream, String filename)
添加文件 (接受输入流)
// 构建InputStream对象
File file = new File(path);
InputStream in = new FileInputStream(file);
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加InputStream对象
.addFile("file", in, "test.jpg");
2
3
4
5
6
7
8
添加字节数组
addFile(String name, byte[] bytes, String filename, String contentType)
添加文件 (接受字节数组)
- 参数
name
: 参数名称- 参数
bytes
: 文件字节数组- 参数
filename
: 文件名, 期望上传的文件数据在服务端保存的文件名- 参数
contentType
: 文件数据的 Content-Type
addFile(String name, byte[] bytes, String filename)
添加文件 (接受字节数组)
// 构建字节数组
byte[] byteArray = IOUtils.toByteArray(url);
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加字节数组
.addFile("file", byteArray, "test.jpg");
2
3
4
5
6
7
添加多个文件
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加File对象1
.addFile("file1", file1);
// 添加File对象2
.addFile("file2", file2);
// 添加File对象3
.addFile("file3", file3);
2
3
4
5
6
7
8
9
# Multipart
在文件上传的时候,除了要添加文件外,通常也要传递一些普通参数
只要在调用 addFile
方法后,再调用 addBody
方法即可
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加File对象
.addFile("file", file)
// 添加 Multipart 参数1
.addBody("name", "foo")
// 添加 Multipart 参数2
.addBody("value", "bar");
2
3
4
5
6
7
8
9
指定Multipart数据项的 Content-Type
addBody(String name, String contentType, Object value) 添加键值对形式Body数据
- 参数
name
: 字段名- 参数
contentType
: 该请求体数据项的Content-Type- 参数
value
: 字段值
Forest.post("/upload")
// 指定请求体为Multipart格式
.contentTypeMultipartFormData()
// 添加File对象
.addFile("file", file)
// 添加 Multipart 参数1,Content-Type 为 text/plian
.addBody("name", "text/plian", "foo")
// 添加 Multipart 参数2,Content-Type 为 text/plian;charset=utf-8
.addBody("value", "text/plian;charset=utf-8", "bar");
2
3
4
5
6
7
8
9