求求你别再用OkHttp调用API接口了,快来试试这款HTTP客户端库吧
引言
在日常业务开发中,我们时常需要使用一些其他公司的服务,调用第三方系统的接口,这时就会涉及到网络请求,通常我们可以使用HttpClient
,OkHttp
等框架去完成网络请求。随着RESTful API的普及,一个高效、简洁且易于维护的HTTP客户端库显得尤为关键。而本文主要介绍一款强大的网络客户端库:Retrofit2
。
Retrofit2简介
Retrofit2是什么?
Retrofit2
是一个由Square公司精心打造并开源的Java
与Android
双平台适用的RESTful API
客户端库,其核心构建在性能卓越的OkHttp
库之上。通过精巧的设计原理,Retrofit2
将原本复杂的HTTP网络请求过程高度抽象为直观且类型安全的接口调用模式,从而极大地简化了应用程序与后端API之间的交互逻辑。
开发者利用Retrofit2
能够以注解驱动的方式来声明和定义API接口,轻松指定HTTP方法、URL路径以及请求参数等关键信息,进而自动生成相应的请求实现代码。该框架不仅支持同步及异步两种调用方式,还内置了对JSON数据序列化和反序列化的自动化处理能力,这意味着无论是发送请求还是解析响应,都能无缝转换成或从对应的Java对象进行操作。
此外,Retrofit2
具备强大的扩展性,允许开发人员根据项目需求定制各种高级功能,如自定义转换器以适应不同数据格式,添加拦截器以实现全局请求/响应处理,以及集成多种认证机制,充分满足现代应用程序中面对复杂网络环境的各种需求。
Retrofit2能做什么?
Retrofit2
的主要功能包括:
类型安全API设计:
Retrofit2
赋予开发者以声明式接口定义的方式来确保网络请求的类型安全性。这意味着通过在接口方法上使用注解来精确指定HTTP请求参数和响应数据结构,框架会自动进行类型校验并确保数据在传输过程中严格符合预期类型,从而消除类型不匹配引发的运行时错误。网络请求流程精简:
Retrofit2
极大地简化了发起网络请求的步骤。开发人员仅需专注于设计与后端服务交互的API接口及相应的HTTP
动作,框架会自动生成底层逻辑代码,无需手动编写创建请求、设置Header
或解析响应内容等繁琐环节,极大地提高了开发效率。内置数据转换机制:为便于数据处理,
Retrofit2
集成了多种数据转换器(Converter
),能够轻松地将从服务器接收到的HTTP原始数据流转换成Java对象,支持常见的数据格式如JSON
、XML
以及其他可通过扩展实现的格式,这使得数据模型与实际业务逻辑之间的映射变得直观且易于管理。异步执行与回调集成:针对移动应用中避免阻塞UI线程的需求,Retrofit2全面支持异步网络请求。它允许开发者采用回调函数或者结合RxJava等反应式编程库来优雅地处理异步任务,确保即便在网络请求执行期间也能保持流畅的用户体验和应用性能。
Retrofit2的优点
代码简化与一致性:通过提供一种声明式的方式来设计和实现网络请求接口,
Retrofit2
极大地减少了开发人员在处理网络通信时所需编写的重复性代码量。开发者仅需关注业务逻辑相关的API描述,无需手动构建和管理复杂的HTTP请求。提升可读性和维护性:框架强调清晰的结构和注解驱动的配置方式,使得网络请求逻辑更加直观且易于理解,进而提高了代码的可读性和维护性。开发者能够快速识别并定位各个网络操作的意义和行为。
类型安全保证:通过集成类型安全的
API
设计,Retrofit2
消除了因参数拼写错误或类型不匹配所引发的运行时异常风险。它确保了数据交换过程中参数类型的正确性,增强了应用的整体健壮性。高效稳定集成:
Retrofit2
无缝集成了高性能的OkHttp
库,充分利用了其在网络连接复用、缓存策略、失败重试等方面的性能优势,从而有效提升了网络请求的执行效率及服务稳定性,为应用程序提供了更强大的网络支持基础架构。
Retrofit2 VS HttpClient
现代化的 API 设计:
Retrofit2
使用现代编程风格,通过注解定义HTTP
请求接口,代码简洁易读。相比之下,HttpClient
需要手动构建Request
和处理响应,代码结构更为繁琐。自动转换数据:
Retrofit2
提供了内置或自定义的数据转换器,如GsonConverterFactory
,可以自动将JSON
或其他格式的数据转换为Java
对象,简化了数据的序列化和反序列化过程。HttpClient
则需要手动处理数据转换,操作相对繁琐。异步与同步支持:
Retrofit2
支持同步和异步两种网络请求方式,提供了基于Call
或Observable
等类型的异步调用方式,方便结合RxJava
等响应式编程框架使用,极大地提升了用户体验和应用程序性能。HttpClient
在异步支持方面较为局限。面向接口编程:
Retrofit2
通过定义服务接口来描述API端点,使得网络层与其他业务逻辑解耦,提高了代码组织性和可测试性。相比之下,HttpClient
直接操作HttpRequest
和HttpResponse
实例,耦合度较高。兼容性与性能:
官方不再推荐使用Apache HttpClient
,而OkHttp
(Retrofit2
底层依赖库)经过持续优化,在性能、连接复用、缓存策略以及对HTTP/2
协议的支持等方面表现更优。易于扩展:
Retrofit2
可以很容易地添加拦截器(Interceptor
)进行诸如身份验证、日志记录和重试机制等功能的扩展。虽然]HttpClient
的扩展性也很强,但需要更多手工编码。社区活跃与更新频繁:
Retrofit2
和OkHttp
社区活跃,更新迭代较快,能快速跟进新的技术和最佳实践,确保开发者能够利用最新的技术改进和安全更新。
Retrofit2
在简化RESTful API
客户端开发、提高效率、易用性、可维护性以及对现代网络特性的支持上均优于旧版的 HttpClient
。
Retrofit2 VS OkHttp
API 接口定义简洁明了:
Retrofit2 使用注解(Annotations)来描述 HTTP 请求方法、URL、参数等,开发者只需通过定义 Java 接口就能清晰地表达出网络调用的意图。相比之下,OkHttp 需要开发者直接处理复杂的 HTTP 请求构建逻辑。自动序列化与反序列化:
Retrofit2 提供了转换器(Converter)支持,如 GsonConverterFactory、JacksonConverterFactory 等,能够自动将 JSON 或其他格式的数据转换为 Java 对象以及相反的操作,极大地简化了数据处理过程。而 OkHttp 需要开发者手动处理数据转换。同步/异步模式统一处理:
Retrofit2 不仅支持同步请求,还对异步请求提供了统一的 Call 或 Observable 返回类型,方便在 Android 中进行非阻塞式编程,并且易于结合 RxJava 等响应式库使用。相比之下,OkHttp 的异步请求处理需要开发者自行管理。丰富的注解体系:
Retrofit2 提供了多种注解以支持不同的请求类型(GET、POST、PUT、DELETE 等)、路径参数、查询参数、表单提交、文件上传、多部分请求等,可以灵活配置请求内容。而 OkHttp 的使用需要开发者手动构建请求参数和处理响应。强大的扩展性:
Retrofit2 支持自定义拦截器(Interceptor),可以在请求前后添加额外的业务逻辑,如认证、日志记录、缓存策略等。同时,可以自由配置 OkHttpClient 实例,充分利用 OkHttp 的所有特性,如连接池、重试机制、HTTP/2 支持等。相比之下,OkHttp 更专注于网络通信的核心功能。代码可读性强:
Retrofit2 将网络请求抽象成一个服务接口的形式,使得代码更易于阅读和维护,提高了整体项目的组织性和整洁度。相比之下,OkHttp 的使用需要开发者更多地关注底层的网络通信细节。降低耦合度:
使用 Retrofit2 可以将网络访问层与应用的其他组件更好地解耦,使得业务逻辑代码更加关注于处理业务本身,而不是如何发起网络请求。相比之下,OkHttp 的使用需要开发者更多地处理网络请求的细节,耦合度较高。
虽然 OkHttp 是一个高性能的 HTTP 客户端,专注于网络通信的核心功能,但 Retrofit2 在此基础上封装了一层高级抽象,让开发者能以声明式的方式编写网络请求代码,降低了复杂度并提升了开发效率。
Retrofit2使用
引入依赖
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
</dependency>
<!-- 示例使用jackson的converter -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-jackson</artifactId>
<version>2.9.0</version>
</dependency>
定义API接口
在Retrofit
框架中,构建与服务器的通信接口是通过定义清晰、结构化的API接口来实现的。这个过程涵盖了详细指定请求方式、路径以及相关参数等关键信息。具体来说,每个接口方法代表了一种特定的HTTP交互模式,明确指示了请求类型(如GET
、POST
、PUT
或DELETE
)和目标URL
路径。
请求方法
在接口方法上应用诸如 @GET
、@POST
、@PUT
和@DELETE
等注解是为了精确映射到相应的HTTP动作。
@POST("user/add")
@GET("user/info/{id}")
// 也可以指定查询参数
@GET("user/list?pageSize=50")
URL操作
利用@Path
、@Query
和@Body
注解能够进一步细化接口描述,分别用于设定路径中的动态变量、查询字符串参数以及HTTP
请求体内容。接口方法可以接受不同类型的参数,这些参数会根据注解类型被正确地插入到请求的不同部分。
使用@Path
注解的参数会在实际调用时将传入值插入到URL
路径中相应的位置
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId);
还可以通过@Query
参数添加查询参数。
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId, @Query("pageSize") Integer pageSize);
对于复杂的查询参数组合,可以使用Map
。
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
请求体
对于请求对象,可以使用@Body
注解指定对象作为HTTP
请求体。@Body
注解通常用于指定将对象作为JSON
格式的数据传输到服务器。当您在 Retrofit 接口方法中使用 @Body
注解时,Retrofit
将会使用内部的转换器(如GsonConverter
或者 JacksonConverter
)将对象转换为JSON
格式的字符串,并将其作为请求的请求体发送到服务器。
通常情况下,@Body
注解用于POST
或者PUT
请求,其中请求的主体包含了要传输的对象的JSON
表示形式。
@POST("users/new")
Call<UserInfoResponse> createUser(@Body UserInfoRequest user);
通常情况下 @Body注解用于指定JSON格式的数据传输,但Retrofit并不会强制要求请求体的格式必须是JSON。您也可以使用其他格式的数据,例如XML或者纯文本,只要在请求体中提供了正确的数据格式,并且服务器能够正确地解析这种格式的数据。
表单数据和Multipart请求
方法还可以声明发送表单数据和多部分请求数据
使用@FormUrlEncoded
,@Field
或者@FieldMap
将发送表单数据。
@FormUrlEncoded
@POST("users/new")
Call<UserInfoResponse> createUser1(@Field("name") String name, @Field("passowrd") String password);
@FormUrlEncoded
@POST("users/new")
Call<UserInfoResponse> createUser2(@FieldMap Map<String, Object> paramMap);
同时他还支持发送多部分请求,例如文件上传。在方法上使用@Multipart
注解用于发送多部分请求,而参数要使用@Part
注解。在Retrofit
接口方法中使用@Multipart
注解时,Retrofit
将会使用multipart/form-data
格式来发送请求,这种格式允许同时上传文本数据和二进制文件数据。
@Multipart
@POST("user/image")
Call<UserInfoResponse> updateUser(@Part("image") RequestBody userImage, @Part("imageDesc") RequestBody imageDesc);
@Part
注解用于声明每个部分的内容,其中可以是RequestBody
类型的文本或者二进制数据,也可以是MultipartBody.Part
类型的文件或者其他二进制数据。这样的话,就可以通过多个@Part
注解来声明不同类型的部分,以满足不同的上传需求
Header信息
使用@Headers
注解为方法设置静态头部。
@Headers({
"Accept: application/json, text/plain, */*",
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Cookie:xxxxxx"
})
@POST("users/new")
Call<UserInfoResponse> createUser(@Body UserInfoRequest user);
使用用@Header
或者HeaderMap
注解动态更新请求头。必须提供相应的参数给@Header
。如果值为 null
,则头部将被省略。否则,将对值调用toString
,并使用结果。
@POST("users/new")
Call<UserInfoResponse> createUser(@Header("Cookie") String cookie, @Body UserInfoRequest user);
@POST("users/new")
Call<UserInfoResponse> createUser2(@HeaderMap Map<String, String> headerMap, @Body UserInfoRequest user);
关于Header参数,我们还可以通过OkHttp的拦截器进行操作。
方法返回值
API接口方法通常返回 Call<T>
类型的对象,这里的T代表期望从服务器接收的数据类型。这种方式使得开发者能方便地利用 Retrofit 提供的回调机制或其他响应式编程库(如RxJava)来处理网络请求的结果,从而确保了对异步操作的良好控制和管理。
public interface MyClientService {
@POST("test/add")
Call<TestResponse> addTest(@Body TestRequest testRequest);
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
}
创建Retrofit实例
Retrofit
框架的核心组件是Retrofit
实例。Retrofit
实例作为整个框架的心脏,不仅负责搭建网络请求所需的基础设施,还承担起发起请求、转换数据和管理响应生命周期的任务。
Retrofit retrofit = new Retrofit.Builder()
// 设置 API 的基础 URL
.baseUrl("http://localhost:8080/coderacademy/")
.addConverterFactory(JacksonConverterFactory.create())
.build();
baseUrl设置
其中baseUrl
用于指定请求服务器的根地址或者API
的基础路径。Retrofit
会自动将baseUrl
和方法注解中的相对路径结合起来生成实际请求的完整URL。例如对上述示例中:
public interface MyClientService {
@POST("test/add")
Call<TestResponse> addTest(@Body TestRequest testRequest);
}
最终的请求url为:localhost:8080/coderacademy/test/add
。
关于baseUrl
的设置有一些注意事项:
baseUrl设置必须以
/
结尾,否则汇报错。
请求方法中的相对路径(不以"/"开头),将会正确附加在以斜杠结尾的 baseUrl 的路径后面。这确保了正确的 URL 结果。如baseUrl
http://localhost:8080/coderacademy/
, 方法url为test/add
,则最终的路径为:localhost:8080/coderacademy/test/add
。请求方法中的绝对路径(以"/"开头),忽略
baseUrl
中的路径组件,只保留host部分,最终的URL
将只包含baseUrl
的主机部分和方法的路径。如baseUrlhttp://localhost:8080/coderacademy/
, 方法url为/test/add
,则最终的路径为:localhost:8080/test/add
。请求方法中的路径可以是完整的
URL
,如果方法路径是完整的URL,则会替换baseUrl
。如baseUrl为http://localhost:8080/coderacademy/
,而方法url为http://localhost:8081/coderacademy/test/add
,则最终的url为:http://localhost:8081/coderacademy/test/add
。
Converter设置
Retrofit
默认只能将HTTP
响应主体反序列化为OkHttp
的ResponseBody
类型,并且只能接受其RequestBody
类型用于@Body
注解。为了支持其他类型,可以添加转换器。
官方提供了8种转换器:
转换器 | 功能 | 使用依赖 |
---|---|---|
Gson | 将 JSON 数据转换为 Java 对象,以及将 Java 对象转换为 JSON 数据。 | com.squareup.retrofit2:converter-gson |
Jackson | 将JSON数据转换为 Java 对象,以及将 Java 对象转换为 JSON 数据。 | com.squareup.retrofit2:converter-jackson |
Moshi | 将 JSON 数据转换为 Java 对象,以及将 Java 对象转换为 JSON 数据。 | com.squareup.retrofit2:converter-moshi |
Protobuf | 将 Protocol Buffers 数据转换为 Java 对象,以及将 Java 对象转换为 Protocol Buffers 数据。 | com.squareup.retrofit2:converter-protobuf |
Wire | 将 Wire 数据转换为 Java 对象,以及将 Java 对象转换为 Wire 数据。 | com.squareup.retrofit2:converter-wire |
Simple XML | 将 XML 数据转换为 Java 对象,以及将 Java 对象转换为 XML 数据。 | com.squareup.retrofit2:converter-simplexml |
JAXB | 将 XML 数据转换为 Java 对象,以及将 Java 对象转换为 XML 数据。 | com.squareup.retrofit2:converter-jaxb |
Scalars | 将原始类型、包装类型和字符串转换为 RequestBody,以及将 ResponseBody 转换为原始类型、包装类型和字符串。 | com.squareup.retrofit2:converter-scalars |
除了官方提供的这几种转换器以外,如果使用了Retrofit 默认不支持的内容格式的API 进行通信(例如YAML 、TXT 、自定义格式),或者使用不同的库来实现现有格式(请求与响应是不同的格式),我们也可以实现自定义转换器。 |
除此之外Retrofit
还可以跟OkHttpClient
搭配使用,实现其高级功能,通过 OkHttpClient
,您可以实现诸如网络连接池、超时设置、重试机制、拦截器等高级功能。而Retrofit
则提供了简化的API
,使得使用这些高级功能变得更加方便。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
.readTimeout(30, TimeUnit.SECONDS) // 设置读取超时时间
.writeTimeout(30, TimeUnit.SECONDS) // 设置写入超时时间
.addInterceptor(new LoggingInterceptor()) // 添加日志拦截器
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 设置自定义的 OkHttpClient
.addConverterFactory(GsonConverterFactory.create())
.build();
创建请求接口实例,发起请求
在创建完Retrofit
实例之后,接下来就需要通过调用Retrofit
实例的create()
方法来创建API
接口的实例。然后就可以使用该实例调用定义在接口中的方法来发起网络请求。
MyClientService myClientService = retrofit.create(MyClientService.class);
TestRequest testRequest = new TestRequest();
testRequest.setName("码农Academy");
testRequest.setPassword("12131");
// 发起请求
Call<TestResponse> call = myClientService.addTest(testRequest);
try {
Response<TestResponse> response = call.execute();
System.out.println("是否请求成功:"+response.isSuccessful());
System.out.println("响应:"+ response.toString());
TestResponse testResponse = response.body();
System.out.println("请求结果:"+ testResponse.toString());
}catch (Exception e){
e.printStackTrace();
}
在Retrofit
中,Call
对象代表了一个待执行的网络请求。它是一个表示单个异步或同步执行的请求的对象。Call
接口定义了执行网络请求和处理响应的方法。Call
接口的泛型类型参数表示了该网络请求的响应类型。例如,Call<TestResponse>
表示该网络请求的响应是一个TestResponse
对象响应。
execute()
方法用于同步执行网络请求,并返回一个Response
对象。当调用execute()
方法时,请求将立即发出,当前线程将被阻塞直到请求完成并返回响应。Response
对象包含了网络请求的响应数据,可以通过调用body()
方法来获取响应主体。
另外,还可以使用Call
对象来发起异步网络请求。异步请求允许您在发出请求后继续执行其他代码,而不必等待网络请求完成。当请求完成后,Retrofit
将在后台线程上调用您提供的回调方法,以处理响应数据。
Call<TestResponse> call = myClientService.addTest(testRequest);
try {
call.enqueue(new Callback<TestResponse>() {
@Override
public void onResponse(Call<TestResponse> call, Response<TestResponse> response) {
System.out.println("是否请求成功:"+response.isSuccessful());
System.out.println("响应:"+ response.toString());
TestResponse testResponse = response.body();
System.out.println("请求结果:"+ testResponse.toString());
}
@Override
public void onFailure(Call<TestResponse> call, Throwable t) {
// 请求失败结果
}
});
}catch (Exception e){
e.printStackTrace();
}
异步请求时,需要实现Callback
接口,该接口定义了处理成功和失败响应的方法。在 onResponse
方法中处理成功响应,在onFailure
方法中处理失败响应。
然后使用Call
对象的enqueue()
方法来执行异步网络请求,并传入Callback
。Retrofit
将在后台线程上执行网络请求,并在请求完成后调用相应的回调方法。
到此一个使用Retrofit2
发起请求的功能就完成了。接下来我们看一下Retrofit2
的一些高级功能。
Retrofit2的高级功能
拦截器
Retrofit
的高级功能通常需要与OkHttpClient
结合使用才能实现。OkHttpClient
是一个强大的HTTP
客户端库,Retrofit
是基于它构建的,并且Retrofit
默认使用 OkHttpClient
作为其底层的网络请求库。
通过OkHttpClient
,您可以实现诸如网络连接池、超时设置、重试机制、拦截器等高级功能。而Retrofit
则提供了简化的API
,使得使用这些高级功能变得更加方便。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
.readTimeout(30, TimeUnit.SECONDS) // 设置读取超时时间
.writeTimeout(30, TimeUnit.SECONDS) // 设置写入超时时间
.addInterceptor(new LoggingInterceptor()) // 添加日志拦截器
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 设置自定义的 OkHttpClient
.addConverterFactory(GsonConverterFactory.create())
.build();
对于拦截器,在实际开发中有较多需要使用的场景,比如第三方服务需要使用一些签名验证手段,请求数据进行加密等,我们都可以统一在拦截器中进行处理。自定义拦截器,我们需要实现Interceptor
接口,实现intercept()
方法。
@Slf4j
public class MyAuthInterceptor implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
String appKey = "MyKey";
String appToken = "MyToken";
Request request = chain.request();
Request.Builder builder = request.newBuilder();
builder.addHeader("Api-Key", appKey).addHeader("Api-Secret", appToken);
request = builder.build();
return chain.proceed(request);
}
}
传入拦截器:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 设置连接超时时间
.readTimeout(30, TimeUnit.SECONDS) // 设置读取超时时间
.writeTimeout(30, TimeUnit.SECONDS) // 设置写入超时时间
.addInterceptor(new LoggingInterceptor()) // 添加日志拦截器
.addInterceptor(new MyAuthInterceptor())
.build();
转换器
前面内容已经提到对于转换器,出了Retrofit2
提供的8种转换器以外,有些特别的请求体这几种转换器不能满足,此时,我们可以自定义转换器。需要继承Converter.Factory
类,重写requestBodyConverter
与reponseBodyConverter
方法即可。
public class CustomBodyConverterFactory extends Converter.Factory {
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new CustomResponseBodyConverter(type);
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new CustomRequestBodyConverter(type);
}
}
然后我们在分别实现CustomResponseBodyConverter
以及CustomRequestBodyConverter
,实现请求与响应不同的转换器。
@Slf4j
public class CustomRequestBodyConverter implements Converter<CustomRequest, RequestBody> {
private final ObjectMapper objectMapper;
public CustomRequestBodyConverter() {
this.objectMapper = new ObjectMapper(new JsonFactoryBuilder().build());
this.objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
this.objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@Nullable
@Override
public RequestBody convert(CustomRequest CustomRequest) throws IOException {
// 具体转换逻辑
}
}
/**
*响应转换器
*/
public class CustomResponseBodyConverter implements Converter<ResponseBody, Object> {
private final Type type;
/**
* 对象映射器
*/
private final Gson gson;
public CustomResponseBodyConverter(Type type) {
this.type = type;
GsonBuilder gsonBuilder = new GsonBuilder();
this.gson = gsonBuilder.create();
}
@Override
public Object convert(ResponseBody value) throws IOException {
// 具体处理逻辑
}
}
使用自定义转换器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 设置自定义的 OkHttpClient
.addConverterFactory(new CustomBodyConverterFactory())
.build();
总结
本文深入介绍了Retrofit2
,这是由Square
公司开源的一款面向Java
和Android
平台的RESTful API
客户端库。基于强大的OkHttp
网络库构建,Retrofit2
通过优雅的设计理念,将复杂的HTTP
请求抽象为类型安全且易于理解的接口调用。
在使用Retrofit2
时,开发者可以利用注解来定义API
接口以及配置请求方法、URL
路径、参数等信息,大大简化了网络通信实现过程,提高了代码可读性和维护性。同时,Retrofit2
内置了多种数据转换器(如GsonConverterFactory
),支持JSON
以及其他格式的数据自动序列化与反序列化,极大地降低了开发成本。
Retrofit2
不仅支持同步和异步两种请求模式,还提供了丰富的扩展机制,包括自定义转换器以适应不同数据格式,添加拦截器处理全局请求/响应逻辑,以及集成各种认证方式,满足复杂网络环境下的各类需求。
此外,本文还阐述了如何创建和配置Retrofit
实例,给出了具体的使用示例,并深入探讨了如何利用高级功能如自定义转换器、拦截器以及进行身份验证等,进一步展示了 Retrofit2
在实际项目中的强大灵活性和实用性。通过本文的学习,读者将能够更加熟练地使用Retrofit2
开发出高效、可靠的网络请求功能。
本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等
求求你别再用OkHttp调用API接口了,快来试试这款HTTP客户端库吧的更多相关文章
- C#使用windows服务定时调用api接口
使用VS创建windows服务项目: 创建好项目 会出现一个设计界面 右键弹出对话框 选择添加安装程序 名字什么的自己可以改: 项目目录: 打开项目中的ProjectInstaller.Design ...
- Python调用API接口的几种方式 数据库 脚本
Python调用API接口的几种方式 2018-01-08 gaoeb97nd... 转自 one_day_day... 修改 微信分享: 相信做过自动化运维的同学都用过API接口来完成某些动作.AP ...
- Python调用API接口的几种方式
Python调用API接口的几种方式 相信做过自动化运维的同学都用过API接口来完成某些动作.API是一套成熟系统所必需的接口,可以被其他系统或脚本来调用,这也是自动化运维的必修课. 本文主要介绍py ...
- 调用API接口,查询手机号码归属地(3)
从mysql数据库获取电话号码,查询归属地并插入到数据库 #!/usr/bin/python # -*- coding: utf-8 -*- import json, urllib, sys, pym ...
- 调用API接口,查询手机号码归属地(2)
使用pymysql pip install pymysql 创建mysql测试表 CREATE TABLE `userinfo` ( `id` int(20) NOT NULL AUTO_INCREM ...
- 调用API接口,查询手机号码归属地(1)
使用https://www.juhe.cn/提供的接口,查询归属地 在官网注册key即可使用. 代码如下 #!/usr/bin/python # -*- coding: utf-8 -*- impor ...
- 怎么调用api接口
api的简单调用,调用api的方法 方法一:用前端方法调用api 完整代码: <!DOCTYPE html> <html lang="en"> <he ...
- Apsara Clouder专项技能认证:实现调用API接口
一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访 ...
- spring boot 通过feign调用api接口
目的:远程调用服务器api,直接上步骤: 1,添加maven依赖,这是必须的: <dependency> <groupId>org.springframework.cloud& ...
- PHP调用API接口实现天气查询功能
天气预报查询接口API,在这里我使用的是国家气象局天气预报接口 使用较多的还有:新浪天气预报接口.百度天气预报接口.google天气接口.Yahoo天气接口等等. 1.查询方式 根据地名查询各城市天气 ...
随机推荐
- Nginx调优总结-第六部分编译优化与简单测试
第六部分 编译优化 Nginx可以自行编译,所以里面可以设置多个编译策略. 也可以自行修改源码,便于比如进行ip_hash的全IP地址验证. 也可以修改nginx的版本号等信息, 避免内发现. 还可以 ...
- linux使用脚本给文件的最后一行不换行的方式插入一句话
处理一下 sed -i '$s/$/&,xxxx.com/' /deploy/mailfailstart
- Mysql到TiDB迁移,双写数据库兜底方案
作者:京东零售 石磊 TiDB 作为开源 NewSQL 数据库的典型代表之一,同样支持 SQL,支持事务 ACID 特性.在通讯协议上,TiDB 选择与 MySQL 完全兼容,并尽可能兼容 MySQL ...
- Unity2019及Unity2020打包android的环境配置
2019安卓打包只有gradle模式了,因为谷歌把adt删了 unity2019可以自定义gradle模板,国内请把repo地址改成阿里云的源 unity2019打apk配置 引擎版本:unity20 ...
- python实现zip分卷压缩与解压
1. python实现zip分卷压缩 WinHex 开始16进制一个一个文件对比 WinRar 创建的分卷压缩和单个 zip 文件的差异. 如果想把单个大文件 test.zip -> 分卷文件 ...
- 金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测股票价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)
金融时间序列预测方法合集:CNN.LSTM.随机森林.ARMA预测股票价格(适用于时序问题).相似度计算.各类评判指标绘图(数学建模科研适用) 1.使用CNN模型预测未来一天的股价涨跌-CNN(卷积神 ...
- TF-VAEGAN:添加潜在嵌入(Latent Embedding)的VAEGAN处理零样本学习
前面介绍了将VAE+GAN解决零样本学习的方法:f-VAEGAN-D2,这里继续讨论引入生成模型处理零样本学习(Zero-shot Learning, ZSL)问题.论文"Latent Em ...
- easyexcel只通过表名来动态查询并动态导出数据
EasyExcel动态表头即动态数据生成 1️⃣ 业务需求 需要将数据库中的所有表放在一个下拉框中,下拉框支持模糊查询到相关的表,然后通过这个表名查询到数据库的数据,切换不同的表查询出来相关表的列和数 ...
- Leetcode刷题第一天-贪心
455-分饼干 链接:455. 分发饼干 - 力扣(LeetCode) 优先使用最小饼干满足最小胃口,一个娃只能分一个饼干T_T不能加 1 class Solution: 2 def findCont ...
- DBGRIDEH 排序 我自己大总结【含DBX,Dac控件】
1.三个属性让DBGridEH可以点击表头自动排序 只要设置下面三个属性: ColumDefValues->Title->TitleButton设为TRUE sortlocal 设为 ...