idtitlesidebar_label
receive_data
接收数据
接收数据

反序列化

Forest请求会自动将响应的返回数据反序列化成您要的数据类型。想要接受指定类型的数据需要完成两步操作:

第一步:定义dataType属性

dataType属性指定了该请求响应返回的数据类型,目前可选的数据类型有三种: text, json, xml

Forest会根据您指定的dataType属性选择不同的反序列化方式。其中dataType的默认值为text,如果您不指定其他数据类型,那么Forest就不会做任何形式的序列化,并以文本字符串的形式返回给你数据。

  1. /**
  2. * dataType为text或不填时,请求响应的数据将以文本字符串的形式返回回来
  3. */
  4. @Request(
  5. url = "http://localhost:8080/text/data",
  6. dataType = "text"
  7. )
  8. String getData();

若您指定为jsonxml,那就告诉了Forest该请求的响应数据类型为JSON或XML形式的数据,就会以相应的形式进行反序列化。

  1. /**
  2. * dataType为json或xml时,Forest会进行相应的反序列化
  3. */
  4. @Request(
  5. url = "http://localhost:8080/text/data",
  6. dataType = "json"
  7. )
  8. Map getData();

第二步:指定反序列化的目标类型

反序列化需要一个目标类型,而该类型其实就是方法的返回值类型,如返回值为String就会反序列成String字符串,返回值为Map就会反序列化成一个HashMap对象,您也可以指定为自定义的Class类型。

  1. public class User {
  2. private String username;
  3. private String score;
  4. // Setter和Getter ...
  5. }

如有上面这样的User类,并把它指定为方法的返回类型,而且相应返回的数据这样一段JSON:

  1. {"username": "Foo", "score": "82"}

那请求接口就应该定义成这样:

  1. /**
  2. * dataType属性指明了返回的数据类型为JSON
  3. */
  4. @Get(
  5. url = "http://localhost:8080/user?id=${0}",
  6. dataType = "json"
  7. )
  8. User getUser(Integer id)

1.4.0版本开始,dataType 属性默认为 auto(自动判断数据类型), 也就是说 dataType 属性可以完全省略不填,Forest会自行判断返回的数据类型是哪种格式。

  1. /**
  2. * 省略dataType属性会自动判断返回的数据格式并进行反序列化
  3. */
  4. @Get("http://localhost:8080/user?id=${0}")
  5. User getUser(Integer id)

返回响应对象

直接用普通的对象类型作为请求方法的返回类型,可以将响应数据方便的反序列化,以满足大部分的需求。但还有很多时候不光需要获取响应内容,也需要得到响应头等信息,这时候就需要 ForestResponse 出场了。

ForestResponse作为请求方法的返回值类型

  1. /**
  2. * ForestResponse 可以作为请求方法的返回类型
  3. * ForestResponse 为带泛型的类,其泛型参数中填的类作为其响应反序列化的目标类型
  4. */
  5. @Post("http://localhost:8080/user")
  6. ForestResponse<String> postUser(@JSONBody User user);

ForestResponse对象接到请求响应数据后便可以获取响应内容

  1. // 以ForestResponse类型变量接受响应数据
  2. ForestResponse<String> response = client.postUser(user);
  3. // 用isError方法去判断请求是否失败
  4. if (response.isError()) {
  5. ... ...
  6. }
  7. // 用isSuccess方法去判断请求是否成功
  8. if (response.isSuccess()) {
  9. ... ...
  10. }
  11. // 以字符串方式读取请求响应内容
  12. String text = response.readAsString();
  13. // getContent方法可以获取请求响应内容文本
  14. // 和readAsString方法不同的地方在于,getContent方法不会读取二进制形式数据内容,
  15. // 而readAsString方法会将二进制数据转换成字符串读取
  16. String content = response.getContent();
  17. // 获取反序列化成对象类型的请求响应内容
  18. // 因为返回类型为ForetReponse<String>, 其泛型参数为String
  19. // 所以这里也用String类型获取结果
  20. String result = response.getResult();
  21. // 以字节数组的形式获取请求响应内容
  22. byte[] byteArray = response.getByteArray();
  23. // 以输入流的形式获取请求响应内容
  24. InputStream in = response.getInputStream();

因为ForestResponse为带泛型的类型,其泛型参数可以是任何其他类型,所以可以根据它的泛型参数中的类型不同,而将响应内容反序列化成不同的对象。

  1. /**
  2. * ForestResponse 可以作为请求方法的返回类型
  3. * ForestResponse 为带泛型的类,其泛型参数中填的类作为其响应反序列化的目标类型
  4. */
  5. @Get("http://localhost:8080/user")
  6. ForestResponse<User> getUser(@Query("id") String userId);

同样是用ForestResponse类型变量去接受响应数据

  1. ForestResponse<User> response = client.postUser(user);
  2. // 判断请求是否成功
  3. if (response.isSuccess()) {
  4. // 通过getResult方法获取其响应内容反序列化后的结果
  5. // 因为返回类型 ForestResponse<User> 中泛型参数为 User,
  6. // 所以得到反序列化后的对象也是User类型对象
  7. User user = response.getResult();
  8. }

拦截器中获取响应对象

  1. public class SimpleInterceptor1 implements Interceptor<String> {
  2. ... ...
  3. /**
  4. * 该方法在请求发送之后被调用
  5. */
  6. @Override
  7. public void afterExecute(ForestRequest request, ForestResponse response) {
  8. // 执行在发送请求之后处理的代码
  9. int status = response.getStatusCode(); // 获取请求响应状态码
  10. String content = response.getContent(); // 获取请求的响应内容
  11. String result = response.getResult(); // 获取方法返回类型对应的最终数据结果
  12. }
  13. }

:::info 提示 拦截器详细内容请参见《拦截器》 :::

回调函数中获取响应对象

  1. @Post("http://localhost:8080/user")
  2. void postUser(@JSONBody User user, OnSuccess<String> onSuccess);
  3. ... ...
  4. client.postUser(user, (String resText, ForestRequest request, ForestResponse response) -> {
  5. // 在成功接收请求响应后处理
  6. int status = response.getStatusCode(); // 获取请求响应状态码
  7. String content = response.getContent(); // 获取请求的响应内容
  8. String result = response.getResult(); // 获取方法返回类型对应的最终数据结果
  9. });

:::info 提示 回调函数详细内容请参见《回调函数》 :::

获取响应头

要获取响应头首先要获取响应对象,也就是ForestResponse对象,这一步可以参见《获取响应对象》。

获取ForestResponse对象后便可以获取响应头了

  1. ForestResponse<String> response = client.textXXX();
  2. // 根据响应头名称获取单个请求响应头
  3. ForestHeader header = response.getHeader("Content-Type");
  4. // 响应头名称
  5. String headerName = header.getName();
  6. // 响应头值
  7. String headerValue = header.getValue();
  8. // 根据响应头名称获取请求响应头列表
  9. List<ForestHeader> heaers = response.getHeaders("Content-Type");
  10. // 根据响应头名称获取请求响应头值
  11. String val = response.getHeaderValue("Content-Type");
  12. // 根据响应头名称获取请求响应头值列表
  13. List<String> vals = response.getHeaderValues("Content-Type");