原文链接:https://futurestud.io/blog/retrofit-send-objects-in-request-body
本篇介绍了在 Retrofit 里如何设置自定义 JSON 转换器。下面的列表显示了该系列的所有文章:
在 Retrofit 2里实现自定义响应转换器是一个复杂的过程. 我们一定会写一篇关于如何在 Retrofit 2中创建和集成自己的响应转换器的另一篇博客. 一旦发布,我们将在此处链接和更新本说明。(原文评论里提到 Retrofit 2的自定义转换器教程不会公开发布了, 有读者自己做了实现, 可以参考, 译者注)
Retrofit 系列目录
- 开始创建android客户端[已翻译]
- Android上的基本认证[已翻译]
- Android上的令牌认证[已翻译]
- Android上的OAuth
- 多个 Query 参数使用同一名字[已翻译]
- 同步与异步请求[已翻译]
- 在请求体里发送对象[已翻译]
- 自定义一个响应转换器
- 添加自定义请求头
- 可选的 Query 参数
- 如何集成 XML 转换器
- 使用 Log Level 调试请求
- 如何上传文件
- Series Round-Up
- Retrofit 2 — 1.9 升级指南
- Retrofit 2 — 如何上传文件
- Retrofit 2 — Log 请求与响应
- Retrofit 2 — Android 上的 Hawk 认证
- Retrofit 2 — 简单错误处理
- 如何在 Retrofit 1 里使用 OkHttp 3
- Retrofit 2 — 图书更新发布庆典
- 提交表单数据 — Urlencoded
- 提交表单数据 — Urlencoded 使用FieldMap
- Retrofit 2 — 在 OkHttp 拦截器里管理请求头部
- Retrofit 2 — 如何给每一个请求添加 Query 参数
- Retrofit 2 — 使用QueryMap 添加多个 Query 参数
- Retrofit 2 — 如何在请求时使用动态 Url
- Retrofit 2 — Url 处理,分辨和解析
- Retrofit 2 — POST 和PUT 请求里的常量, 默认值和逻辑值
- Retrofit 2 — 如何下载文件
- Retrofit 2 — 取消请求
- Retrofit 2 — 重用分析请求
- Retrofit 2 — 如何在运行时修改 API Base Url
- 可选Path参数
- 如何刷新 Access Token
- Retrofit 2 — 如何提交文本请求体
- Retrofit 2 — 使用 Query 参数来分页
- Retrofit 2 — 使用 链接头和动态 Url 来分页(比如GitHub)
- Retrofit 2 — 使用范围头字段来分页 (比如 Heroku)
- Retrofit 2 — 转换器介绍
- Retrofit 2 — 添加并自定义 Gson 转换器
- Retrofit 2 — 实现自定义转换器
- Retrofit 2 — 只在开发环境里启用日志
- Retrofit 2 — 如何上传多个文件
- Retrofit 2 — Passing Multiple Parts Along a File with @PartMap
- Retrofit 2 — 模仿服务端响应基本概念
- Retrofit 2 — 模仿服务端响应自定义网络行为
- Retrofit 2 — 使用 @HeaderMap 定义动态请求头
基础
Retrofit 默认附带了 Google's JSON. 每个JSON映射都在GSON的帮助下完成. 有时候,你的框架或属性需要改变集成的JSON转换器. 一个著名的转换器是 Jackson. 我们将使用 Jackson 做为代码示例.
现有的 Retrofit 转换器
除了 GSON, Retrofit 可被配置成各种内容格式. retrofit-converters 目录列出了现有的响应转换器:
与gradle的整合可以用以下命令来完成:
compile 'com.squareup.retrofit:converter-<converter-name>:1.9.0'
# e.g. Jackson
compile 'com.squareup.retrofit:converter-jackson:1.9.0'
# e.g. XML
compile 'com.squareup.retrofit:converter-simplexml:1.9.0'
你应该知道如何整合 protocol buffers :)
创建你自己的转换器
一旦你需要或想要创建自己的 Retrofit 响应转换器,你可以按照下面的步骤. 我们将使用 Jackson 库来说明具体的定义和处理.
记住: 目前已有的 Retrofit 转换器 你可以通过集成各自的gradle依赖直接使用它们.
Jackson Gradle 依赖
首先, 定义 Jackson 依赖. 本例使用的是 Jackson 2.x ,与以前的 Jackson 1.x 有很大的不同. 添加需要的 Maven 库和编译依赖.
repositories {
maven { url "http://repository.codehaus.org/org/codehaus" }
}
dependencies {
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.3'
}
实现自定义的 JSON 转换器
替换 Retrofit 的 JSON 转换器最重要的部分是实现 Converter
接口并覆盖两个方法: fromBody
and toBody
.
public class JacksonConverter implements Converter {
private ObjectMapper mapper = new ObjectMapper();
@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
JavaType javaType = mapper.getTypeFactory().constructType(type);
try {
return mapper.readValue(body.in(), javaType);
} catch (IOException e) {
throw new ConversionException(e);
}
}
@Override
public TypedOutput toBody(Object object) {
try {
String charset = "UTF-8";
String json = mapper.writeValueAsString(object);
return new JsonTypedOutput(json.getBytes(charset));
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static class JsonTypedOutput implements TypedOutput {
private final byte[] jsonBytes;
JsonTypedOutput(byte[] jsonBytes) { this.jsonBytes = jsonBytes; }
@Override public String fileName() { return null; }
@Override public String mimeType() { return "application/json; charset=UTF-8"; }
@Override public long length() { return jsonBytes.length; }
@Override public void writeTo(OutputStream out) throws IOException { out.write(jsonBytes); }
}
}
JsonTypedOutput
类被用来设置正确的 mimeType. 由于输出类型是JSON, mime 类型也应该是 application/json
.
设置自定义JSON转换器
Retrofit 的 JSON转换器被集成在RestAdapter
里. 通过调用RestAdapter
对象的setConverter()
方法可以改变转换器. 此外, 当创建 rest 客户端时, 你可以在RestAdapter
的构建过程里直接设置转换器来集成 jackson 转换器.
// Create our Converter
JacksonConverter jacksonConverter = new JacksonConverter();
// Build the Retrofit REST adaptor pointing to the URL specified, with the Converter.
// Note: The Converter must be set before the .build() command
RestAdapter restAdapter = new RestAdapter.Builder()
.setConverter(jacksonConverter)
.setEndpoint("https://api.example.com/")
.build();
干得漂亮! 以后你创建的所有RestAdapter
都将使用 JacksonConverter 来处理 JSON.
如果你遇到任何问题或困难, 请 Twitter @futurestud_io.