Retrofit

一个用于 Android 和 Java 的类型安全的 HTTP 客户端

介绍

Retrofit 将您的 HTTP API 转换为 Java 接口。

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

Retrofit 类生成 GitHubService 接口的一个实现。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

从创建的 GitHubService 中的每个 Call 都可以向远程 Web 服务器发出同步或异步 HTTP 请求。

Call<List<Repo>> repos = service.listRepos("octocat");

使用注解来描述 HTTP 请求

  • 支持 URL 参数替换和查询参数
  • 对象转换为请求体(例如,JSON,Protocol Buffers)
  • Multipart 请求体和文件上传

API 声明

接口方法及其参数上的注解指示了请求将如何处理。

请求方法

每个方法都必须有一个 HTTP 注解,用于提供请求方法和相对 URL。有八个内置注解:HTTPGETPOSTPUTPATCHDELETEOPTIONSHEAD。资源的相对 URL 在注解中指定。

@GET("users/list")

您还可以在 URL 中指定查询参数。

@GET("users/list?sort=desc")

URL 操作

请求 URL 可以使用方法上的替换块和参数进行动态更新。替换块是由 {} 包围的字母数字字符串。相应的参数必须使用相同的字符串通过 @Path 进行注解。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

也可以添加查询参数。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

对于复杂的查询参数组合,可以使用 Map

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

请求体

可以使用 @Body 注解指定一个对象作为 HTTP 请求体。

@POST("users/new")
Call<User> createUser(@Body User user);

对象还将使用 Retrofit 实例上指定的转换器进行转换。如果未添加转换器,则只能使用 RequestBody

表单编码和 Multipart

方法也可以被声明为发送表单编码和 multipart 数据。

当方法上存在 @FormUrlEncoded 时,发送表单编码数据。每个键值对都使用 @Field 进行注解,其中包含名称和提供值的对象。

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

当方法上存在 @Multipart 时,使用 Multipart 请求。各部分使用 @Part 注解声明。

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

Multipart 部分使用 Retrofit 的转换器之一,或者它们可以实现 RequestBody 来处理自己的序列化。

头部操作

您可以使用 @Headers 注解为方法设置静态头部。

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);

注意,头部不会互相覆盖。所有同名的头部都将包含在请求中。

请求头部可以使用 @Header 注解进行动态更新。必须为 @Header 提供相应的参数。如果值为 null,则将省略该头部。否则,将对该值调用 toString 方法,并使用其结果。

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

与查询参数类似,对于复杂的头部组合,可以使用 Map

@GET("user")
Call<User> getUser(@HeaderMap Map<String, String> headers)

需要添加到每个请求的头部可以使用 OkHttp interceptor 来指定。

同步 vs. 异步

Call 实例可以同步或异步执行。每个实例只能使用一次,但调用 clone() 将创建一个可用的新实例。

在 Android 上,回调将在主线程执行。在 JVM 上,回调将在执行 HTTP 请求的同一线程上发生。

Kotlin 支持

接口方法支持 Kotlin suspend 函数,这些函数直接返回一个 Response 对象,在挂起当前函数的同时创建并异步执行调用。

@GET("users")
suspend fun getUser(): Response<User>

Suspend 方法也可以直接返回 body。如果返回非 2XX 状态,则会抛出包含响应的 HttpException

@GET("users")
suspend fun getUser(): User

Retrofit 配置

Retrofit 是一个类,通过它您的 API 接口可以转换为可调用的对象。默认情况下,Retrofit 会为您的平台提供合理的默认设置,但也允许自定义。

转换器

默认情况下,Retrofit 只能将 HTTP body 反序列化为 OkHttp 的 ResponseBody 类型,并且只能接受其 RequestBody 类型作为 @Body

可以添加转换器以支持其他类型。附带的模块适配了流行的序列化库,以方便您使用。

  • Gson: com.squareup.retrofit2:converter-gson
  • Jackson: com.squareup.retrofit2:converter-jackson
  • Moshi: com.squareup.retrofit2:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire
  • Simple XML: com.squareup.retrofit2:converter-simplexml
  • JAXB: com.squareup.retrofit2:converter-jaxb
  • Scalars(基本类型、包装类型和 String):com.squareup.retrofit2:converter-scalars

这里是一个使用 GsonConverterFactory 类生成 GitHubService 接口实现的示例,该实现使用 Gson 进行反序列化。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);

自定义转换器

如果您需要与使用 Retrofit 不原生支持的内容格式(例如 YAML、txt、自定义格式)的 API 进行通信,或者您希望使用不同的库来实现现有格式,您可以轻松创建自己的转换器。创建一个继承自 Converter.Factory 的类,并在构建适配器时传入一个实例。

下载

最新 JAR

Retrofit 的源代码、其示例以及本网站可在 GitHub 上获取。

Maven

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>(insert latest version)</version>
</dependency>

Gradle

implementation 'com.squareup.retrofit2:retrofit:(insert latest version)'

Retrofit 最低需要 Java 8+ 或 Android API 21+。

R8 / ProGuard

如果您使用 R8,则会自动包含混淆和优化规则。

ProGuard 用户必须手动添加来自 retrofit2.pro 的选项。

您可能还需要针对 OkHttpOkio 的规则,它们是此库的依赖项。

贡献

如果您想贡献代码,您可以通过 GitHub 通过 fork 仓库并发送 pull request 来实现。

提交代码时,请尽量遵循现有约定和风格,以便代码尽可能保持可读性。另请确保通过运行 ./gradlew build(或 Windows 上的 gradlew.bat build)来编译您的代码。

在您的代码被接受到项目之前,您还必须签署个人贡献者许可协议(CLA)

许可

Copyright 2013 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   https://apache.ac.cn/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.