这是一个类型安全的Http客户端Java实现,当然也可以用于Android的App开发,它使用注解和接口来定义各种Rest API,使得调用变得十分的方便和易于管理。

快速入门

Retrofit使用Java中的接口来定义各种Http API:

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

 

Retrofit会为我们的接口生成对应的调用实现,我们再也不必去创建一个httpClient对象处理请求响应,也不需要使用spring的restTemplate那种stupid方法,Retrofit类生成一个GitHubService的实现:

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

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

 

调用这个Retrofit为我们生成的实现中的方法会返回一个Call对象,每个从GitHubService创建的Call对象都可以发送一个异步或者同步的Http请求到远端服务器:

Call<List<Repo>> repos = service.listRepos("octocat");
try {
    List<Repo> list = call.execute().body();
} catch (Exception e) {
    LOG.error("Error when call checkToken: ", e);
}

 

Retrofit 使用注解来描述Http请求,支持以下功能:

  • 支持URL参数占位符和查询参数
  • 将一个对象转换成请求实体 (例如 JSON, 协议缓冲(原文:protocol buffers))
  • Multipart 类型的请求实体(表单)和文件上传

API定义

注解标注在接口方法上,注解的参数指示请求将被如何处理。

 

请求方法

每个接口方法都必须有一个Http注解,他提供了发送HTTP请求方法类型和资源的相对URL。有5个注解可供选择:GET POST PUT DELETE 和HEAD。资源的相对URL在注解参数中指定:

@GET("/users/list")

你可以在URL中指定查询参数:

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

 

URL设置

可以通过在接口方法上的注解中使用占位符和查询参数实现动态URL,一个占位符是一个包含在大括号{ }中的字母或数字字符串。相应的,必须使用@Path和相同的占位字符串标注接口方法中对应的参数:

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

也可以添加查询参数:

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

可以使用Map来封装复杂的请求参数:

@GET("/group/{id}/users")
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(如果没有指定转换器那么复合参数必须实现RequestBody接口)。

 

表单编码和MULTIPART

接口方法也可以被定义用于发送form-encoded 和 multipart 数据。
当@FormUrlEncoded注解出现在方法上时发送的数据将是表单编码格式的。使用@Field标注接口中的每个参数键值对:

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

 

当@Multipart出现在方法上方时将使用Multipart请求,使用@Part定义每一个Parts:

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

Multipart中的parts将使用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标签即可,在接口方法中同样必须提供对应的参数,如果参数值为null,则该请求头会被忽略,否则将调用该参数的toString方法,返回值将作为请求头的值。

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

如果需要在每一个请求中设置指定的请求头,可以使用一个OkHttp的拦截器完成。

 

同步和异步

Call实例可以是同步执行也可以是异步执行的。每个实例都只能使用一次,但可以使用clone()方法创建一个新的可用实例。
在安卓中回调将在主线程中执行。在普通JVM环境中,回调将在执行HTTP请求的相同线程中执行。

 

Retrofit配置

Retrofit将你的API接口变成了可调用的对象。默认的情况下,Retrofit将会根据运行平台选择不同的配置,但它也允许自定义。

 

转换器

在默认的情况下,Retrofit只能将HTTP响应解析成OkHttp的ResponseBody类型,并且使用@Body标注的请求参数也只能是RequestBody类型。
如果添加了转换器则可以支持其他类型,你可以使用以下6个热门的序列化实现库来进行转换:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi
  • Protobuf: com.squareup.retrofit:converter-protobuf
  • Wire: com.squareup.retrofit:converter-wire
  • Simple XML: com.squareup.retrofit:converter-simplexml

示例代码:

Retrofit retrofit = new Retrofit.Builder()
	.baseUrl("url")
	.addConverterFactory(JacksonConverterFactory.create()) //设置转换工厂
	.build();

 

自定义转换器

如果你需要使用一种Retrofit不支持的方式来进行API通信(例如: YAML, txt, 自定义格式),或者你希望使用一个不同的序列化库,你可以通过创建你自己的转换器来实现。创建一个类继承Converter.Factory,然后在创建接口实现的时候设置进去即可。

spring boot + IDEA 远程调试

配置 若想调试远端web容器内部的应用,需要接入web容器的jvm,以Tomcat为例,需修改web容器的配置 // bin\startup.bat(.sh)文件,在里面添加 // windo...

阅读全文

将新建项目上传至远端Git库

git init 
git add . 
git status 
git commit -m "first"
 git remote add origin http://192.168.*:3000/cjds-backend-develop/cjds-auth...

阅读全文

Maven上使用maven-source-plugin打包源码

项目比较复杂的时候一般分成多个项目多人进行开发,使用maven进行模块依赖管理。当你引用了别的开发人员的某个jar包,你会发现该jar包中的每个方法的注释都没...

阅读全文

欢迎留言