📬 接收数据
# 反序列化
Forest请求会自动将响应的返回数据反序列化成您要的数据类型。想要接受指定类型的数据需要完成两步操作:
第一步:定义dataType
属性
dataType
属性指定了该请求响应返回的数据类型,目前可选的数据类型有三种: text
, json
, xml
Forest会根据您指定的dataType
属性选择不同的反序列化方式。其中dataType
的默认值为text
,如果您不指定其他数据类型,那么Forest就不会做任何形式的序列化,并以文本字符串的形式返回给你数据。
/**
* dataType为text或不填时,请求响应的数据将以文本字符串的形式返回回来
*/
@Request(
url = "http://localhost:8080/text/data",
dataType = "text"
)
String getData();
2
3
4
5
6
7
8
若您指定为json
或xml
,那就告诉了Forest该请求的响应数据类型为JSON或XML形式的数据,就会以相应的形式进行反序列化。
/**
* dataType为json或xml时,Forest会进行相应的反序列化
*/
@Request(
url = "http://localhost:8080/text/data",
dataType = "json"
)
Map getData();
2
3
4
5
6
7
8
第二步:指定反序列化的目标类型
反序列化需要一个目标类型,而该类型其实就是方法的返回值类型,如返回值为String
就会反序列成String
字符串,返回值为Map
就会反序列化成一个HashMap对象,您也可以指定为自定义的Class类型。
public class User {
private String username;
private String score;
// Setter和Getter ...
}
2
3
4
5
6
如有上面这样的User类,并把它指定为方法的返回类型,而且相应返回的数据这样一段JSON:
{"username": "Foo", "score": "82"}
那请求接口就应该定义成这样:
/**
* dataType属性指明了返回的数据类型为JSON
*/
@Get(
url = "http://localhost:8080/user?id=${0}",
dataType = "json"
)
User getUser(Integer id)
2
3
4
5
6
7
8
从1.4.0
版本开始,dataType
属性默认为 auto
(自动判断数据类型), 也就是说 dataType
属性可以完全省略不填,Forest会自行判断返回的数据类型是哪种格式。
/**
* 省略dataType属性会自动判断返回的数据格式并进行反序列化
*/
@Get("http://localhost:8080/user?id=${0}")
User getUser(Integer id)
2
3
4
5
# 字段命名匹配问题
在使用自定义类型作为接口返回类型,接受服务端响应的数据时,往往会碰到接收到的字段名与 Java 类中字段名的命名风格不匹配的情况(比如接收到的是 user_id, 而 Java 类中却是 userId),对于此类问题请参见《对象字段》
# 返回请求对象
如果将ForestRequest
作为请求方法的返回值类型,调用该方法时不会立即执行请求发送的过程,而是直接返回一个ForestRequest
对象。
这样做的好处是,可以延迟发送HTTP请求,并对要即将发送的请求参数做进一步的修改和加工。
public interface MyForestClient {
/**
* Get类型请求,url路径为 /test
* <p>ForestRequest是带泛型参数的类型
* <p>泛型参数代表返回的响应数据所期望转化成的类型
*
* @return Forest请求对象
*/
@Get("/test")
ForestRequest<?> getForestRequest();
}
2
3
4
5
6
7
8
9
10
11
12
在调用getForestRequest()
方法后获得该请求方法所对应的请求对象
// 如果请求方法以 ForestRequest 作为返回值类型
// 不会直接发送请求
// 而是直接返回 Forest 请求对象
ForestRequest<?> request = myForestClient.getForestRequest();
String path = request.path(); // 得到字符串 /test
// 手动执行发送请求,并以字符串形式接受响应数据
String ret = request.execute(String.class);
2
3
4
5
6
7
获得 Forest 请求对象时并不会自动发送请求,需要调用execute()
或execute(Class)
这类方法手动执行请求发送的过程。
文档导航
要详细了解如何手动执行请求发送,请参见《执行请求》
# 返回响应对象
直接用普通的对象类型作为请求方法的返回类型,可以将响应数据方便的反序列化,以满足大部分的需求。但还有很多时候不光需要获取响应内容,也需要得到响应头等信息,这时候就需要 ForestResponse
出场了。
将ForestResponse
作为请求方法的返回值类型
/**
* ForestResponse 可以作为请求方法的返回类型
* ForestResponse 为带泛型的类,其泛型参数中填的类作为其响应反序列化的目标类型
*/
@Post("http://localhost:8080/user")
ForestResponse<String> postUser(@JSONBody User user);
2
3
4
5
6
7
用ForestResponse
对象接到请求响应数据后便可以获取响应内容
// 以ForestResponse类型变量接受响应数据
ForestResponse<String> response = client.postUser(user);
// 用isError方法去判断请求是否失败
if (response.isError()) {
... ...
}
// 用isSuccess方法去判断请求是否成功
if (response.isSuccess()) {
... ...
}
// 以字符串方式读取请求响应内容
String text = response.readAsString();
// getContent方法可以获取请求响应内容文本
// 和readAsString方法不同的地方在于,getContent方法不会读取二进制形式数据内容,
// 而readAsString方法会将二进制数据转换成字符串读取
String content = response.getContent();
// 获取反序列化成对象类型的请求响应内容
// 因为返回类型为ForetReponse<String>, 其泛型参数为String
// 所以这里也用String类型获取结果
String result = response.getResult();
// 以字节数组的形式获取请求响应内容
byte[] byteArray = response.getByteArray();
// 以输入流的形式获取请求响应内容
InputStream in = response.getInputStream();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
因为ForestResponse
为带泛型的类型,其泛型参数可以是任何其他类型,所以可以根据它的泛型参数中的类型不同,而将响应内容反序列化成不同的对象。
/**
* ForestResponse 可以作为请求方法的返回类型
* ForestResponse 为带泛型的类,其泛型参数中填的类作为其响应反序列化的目标类型
*/
@Get("http://localhost:8080/user")
ForestResponse<User> getUser(@Query("id") String userId);
2
3
4
5
6
7
同样是用ForestResponse
类型变量去接受响应数据
ForestResponse<User> response = client.postUser(user);
// 判断请求是否成功
if (response.isSuccess()) {
// 通过getResult方法获取其响应内容反序列化后的结果
// 因为返回类型 ForestResponse<User> 中泛型参数为 User,
// 所以得到反序列化后的对象也是User类型对象
User user = response.getResult();
}
2
3
4
5
6
7
8
# 拦截器中获取响应对象
public class SimpleInterceptor1 implements Interceptor<String> {
... ...
/**
* 该方法在请求发送之后被调用
*/
@Override
public void afterExecute(ForestRequest request, ForestResponse response) {
// 执行在发送请求之后处理的代码
int status = response.getStatusCode(); // 获取请求响应状态码
String content = response.getContent(); // 获取请求的响应内容
String result = response.getResult(); // 获取方法返回类型对应的最终数据结果
}
}
2
3
4
5
6
7
8
9
10
11
12
13
文档导航
拦截器详细内容请参见《拦截器》
# 回调函数中获取响应对象
@Post("http://localhost:8080/user")
void postUser(@JSONBody User user, OnSuccess<String> onSuccess);
... ...
client.postUser(user, (String resText, ForestRequest request, ForestResponse response) -> {
// 在成功接收请求响应后处理
int status = response.getStatusCode(); // 获取请求响应状态码
String content = response.getContent(); // 获取请求的响应内容
String result = response.getResult(); // 获取方法返回类型对应的最终数据结果
});
2
3
4
5
6
7
8
9
10
11
文档导航
回调函数详细内容请参见《回调函数》
# 获取响应头
要获取响应头首先要获取响应对象,也就是ForestResponse
对象,这一步可以参见《获取响应对象》。
获取ForestResponse
对象后便可以获取响应头了
ForestResponse<String> response = client.textXXX();
// 根据响应头名称获取单个请求响应头
ForestHeader header = response.getHeader("Content-Type");
// 响应头名称
String headerName = header.getName();
// 响应头值
String headerValue = header.getValue();
// 根据响应头名称获取请求响应头列表
List<ForestHeader> heaers = response.getHeaders("Content-Type");
// 根据响应头名称获取请求响应头值
String val = response.getHeaderValue("Content-Type");
// 根据响应头名称获取请求响应头值列表
List<String> vals = response.getHeaderValues("Content-Type");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19