引言

在日常业务开发中,我们时常需要使用一些其他公司的服务,调用第三方系统的接口,这时就会涉及到网络请求,通常我们可以使用
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
的主要功能包括:

  1. 类型安全API设计

    Retrofit2
    赋予开发者以声明式接口定义的方式来确保网络请求的类型安全性。这意味着通过在接口方法上使用注解来精确指定HTTP请求参数和响应数据结构,框架会自动进行类型校验并确保数据在传输过程中严格符合预期类型,从而消除类型不匹配引发的运行时错误。

  2. 网络请求流程精简

    Retrofit2
    极大地简化了发起网络请求的步骤。开发人员仅需专注于设计与后端服务交互的API接口及相应的
    HTTP
    动作,框架会自动生成底层逻辑代码,无需手动编写创建请求、设置
    Header
    或解析响应内容等繁琐环节,极大地提高了开发效率。

  3. 内置数据转换机制
    :为便于数据处理,
    Retrofit2
    集成了多种数据转换器(
    Converter
    ),能够轻松地将从服务器接收到的HTTP原始数据流转换成Java对象,支持常见的数据格式如
    JSON

    XML
    以及其他可通过扩展实现的格式,这使得数据模型与实际业务逻辑之间的映射变得直观且易于管理。

  4. 异步执行与回调集成
    :针对移动应用中避免阻塞UI线程的需求,Retrofit2全面支持异步网络请求。它允许开发者采用回调函数或者结合RxJava等反应式编程库来优雅地处理异步任务,确保即便在网络请求执行期间也能保持流畅的用户体验和应用性能。

Retrofit2的优点

  1. 代码简化与一致性
    :通过提供一种声明式的方式来设计和实现网络请求接口,
    Retrofit2
    极大地减少了开发人员在处理网络通信时所需编写的重复性代码量。开发者仅需关注业务逻辑相关的API描述,无需手动构建和管理复杂的HTTP请求。

  2. 提升可读性和维护性
    :框架强调清晰的结构和注解驱动的配置方式,使得网络请求逻辑更加直观且易于理解,进而提高了代码的可读性和维护性。开发者能够快速识别并定位各个网络操作的意义和行为。

  3. 类型安全保证
    :通过集成类型安全的
    API
    设计,
    Retrofit2
    消除了因参数拼写错误或类型不匹配所引发的运行时异常风险。它确保了数据交换过程中参数类型的正确性,增强了应用的整体健壮性。

  4. 高效稳定集成

    Retrofit2
    无缝集成了高性能的
    OkHttp
    库,充分利用了其在网络连接复用、缓存策略、失败重试等方面的性能优势,从而有效提升了网络请求的执行效率及服务稳定性,为应用程序提供了更强大的网络支持基础架构。

Retrofit2 VS HttpClient

  1. 现代化的 API 设计

    Retrofit2
    使用现代编程风格,通过注解定义
    HTTP
    请求接口,代码简洁易读。相比之下,
    HttpClient
    需要手动构建
    Request
    和处理响应,代码结构更为繁琐。

  2. 自动转换数据

    Retrofit2
    提供了内置或自定义的数据转换器,如
    GsonConverterFactory
    ,可以自动将
    JSON
    或其他格式的数据转换为
    Java
    对象,简化了数据的序列化和反序列化过程。
    HttpClient
    则需要手动处理数据转换,操作相对繁琐。

  3. 异步与同步支持

    Retrofit2
    支持同步和异步两种网络请求方式,提供了基于
    Call

    Observable
    等类型的异步调用方式,方便结合
    RxJava
    等响应式编程框架使用,极大地提升了用户体验和应用程序性能。
    HttpClient
    在异步支持方面较为局限。

  4. 面向接口编程

    Retrofit2
    通过定义服务接口来描述API端点,使得网络层与其他业务逻辑解耦,提高了代码组织性和可测试性。相比之下,
    HttpClient
    直接操作
    HttpRequest

    HttpResponse
    实例,耦合度较高。

  5. 兼容性与性能

    官方不再推荐使用
    Apache HttpClient
    ,而
    OkHttp

    Retrofit2
    底层依赖库)经过持续优化,在性能、连接复用、缓存策略以及对
    HTTP/2
    协议的支持等方面表现更优。

  6. 易于扩展

    Retrofit2
    可以很容易地添加拦截器(
    Interceptor
    )进行诸如身份验证、日志记录和重试机制等功能的扩展。虽然]
    HttpClient
    的扩展性也很强,但需要更多手工编码。

  7. 社区活跃与更新频繁

    Retrofit2

    OkHttp
    社区活跃,更新迭代较快,能快速跟进新的技术和最佳实践,确保开发者能够利用最新的技术改进和安全更新。

Retrofit2
在简化
RESTful API
客户端开发、提高效率、易用性、可维护性以及对现代网络特性的支持上均优于旧版的
HttpClient

Retrofit2 VS OkHttp

  1. API 接口定义简洁明了

    Retrofit2 使用注解(Annotations)来描述 HTTP 请求方法、URL、参数等,开发者只需通过定义 Java 接口就能清晰地表达出网络调用的意图。相比之下,OkHttp 需要开发者直接处理复杂的 HTTP 请求构建逻辑。

  2. 自动序列化与反序列化

    Retrofit2 提供了转换器(Converter)支持,如 GsonConverterFactory、JacksonConverterFactory 等,能够自动将 JSON 或其他格式的数据转换为 Java 对象以及相反的操作,极大地简化了数据处理过程。而 OkHttp 需要开发者手动处理数据转换。

  3. 同步/异步模式统一处理

    Retrofit2 不仅支持同步请求,还对异步请求提供了统一的 Call 或 Observable 返回类型,方便在 Android 中进行非阻塞式编程,并且易于结合 RxJava 等响应式库使用。相比之下,OkHttp 的异步请求处理需要开发者自行管理。

  4. 丰富的注解体系

    Retrofit2 提供了多种注解以支持不同的请求类型(GET、POST、PUT、DELETE 等)、路径参数、查询参数、表单提交、文件上传、多部分请求等,可以灵活配置请求内容。而 OkHttp 的使用需要开发者手动构建请求参数和处理响应。

  5. 强大的扩展性

    Retrofit2 支持自定义拦截器(Interceptor),可以在请求前后添加额外的业务逻辑,如认证、日志记录、缓存策略等。同时,可以自由配置 OkHttpClient 实例,充分利用 OkHttp 的所有特性,如连接池、重试机制、HTTP/2 支持等。相比之下,OkHttp 更专注于网络通信的核心功能。

  6. 代码可读性强

    Retrofit2 将网络请求抽象成一个服务接口的形式,使得代码更易于阅读和维护,提高了整体项目的组织性和整洁度。相比之下,OkHttp 的使用需要开发者更多地关注底层的网络通信细节。

  7. 降低耦合度

    使用 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设置必须以
    /
    结尾,否则汇报错。
    image.png

  • 请求方法中的相对路径(不以"/"开头),将会正确附加在以斜杠结尾的 baseUrl 的路径后面。这确保了正确的 URL 结果。如baseUrl
    http://localhost:8080/coderacademy/
    , 方法url为
    test/add
    ,则最终的路径为:
    localhost:8080/coderacademy/test/add

  • 请求方法中的绝对路径(以"/"开头),忽略
    baseUrl
    中的路径组件,只保留host部分,最终的
    URL
    将只包含
    baseUrl
    的主机部分和方法的路径。如baseUrl
    http://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、中间件、架构设计、面试题、程序员攻略等

标签: none

添加新评论