Retrofit 作为 OkHttp 的上层封装,核心通过 Converter.Factory 实现「请求参数序列化」和「响应数据反序列化」,不同数据格式对应不同的 Converter 实现。以下是 JSON、表单、XML、Protobuf 四种主流格式的完整使用步骤(含依赖、配置、接口定义、调用示例),所有代码均基于 Android 实战场景,可直接复用。
核心前提
- Converter 核心作用 :Retrofit 本身不处理数据序列化,需通过
Converter.Factory将「Java/Kotlin 对象」转为「对应格式的请求体」,或把「响应体」转回对象。 - Content-Type 必须匹配 :每种格式对应固定的
Content-Type请求头,否则服务端无法解析(OkHttp 可通过拦截器统一设置)。 - 基础依赖(必加):无论哪种格式,先添加 OkHttp+Retrofit 核心依赖:
gradle
// 核心依赖(Module 级 build.gradle)
dependencies {
// OkHttp
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0' // 日志拦截器(调试用)
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}
一、JSON 格式(最常用)
1. 核心依赖
JSON 序列化默认用 Gson,需添加 Gson Converter:
gradle
// Gson Converter(JSON 序列化/反序列化)
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// Gson 核心库(可选,自定义序列化规则时用)
implementation 'com.google.code.gson:gson:2.10.1'
2. OkHttp/Retrofit 配置
kotlin
import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
// 1. 配置 OkHttp(含日志、超时、请求头)
private val okHttpClient = OkHttpClient.Builder()
// 日志拦截器(调试时打印请求/响应)
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY // 打印完整日志
})
// 统一设置 JSON 请求头
.addInterceptor { chain ->
val modifiedRequest = chain.request().newBuilder()
.header("Content-Type", "application/json;charset=utf-8") // JSON 专属 Content-Type
.header("Accept", "application/json") // 声明接收 JSON 响应
.build()
chain.proceed(modifiedRequest)
}
// 超时配置
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
// 2. 配置 Retrofit(添加 Gson Converter)
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/") // 替换为你的 BaseUrl
.client(okHttpClient)
// 自定义 Gson 序列化规则(可选,如日期格式、空值处理)
.addConverterFactory(GsonConverterFactory.create(
GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss") // 统一日期格式
.serializeNulls() // 序列化空值(默认不序列化)
.create()
))
.build()
3. 接口定义(ApiService)
JSON 请求用 @Body 传递实体类,无需额外注解:
kotlin
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
// 通用响应体
data class BaseResponse<T>(
val code: Int,
val msg: String,
val data: T?
)
// 用户请求体(JSON 序列化)
data class UserReq(
val username: String,
val password: String,
val createTime: String? = null
)
// 用户响应体
data class UserResp(
val id: String,
val username: String,
val token: String
)
// API 接口定义
interface ApiService {
/**
* POST JSON 请求(创建用户)
* 请求体:UserReq 自动序列化为 JSON
*/
@POST("v1/users")
suspend fun createUser(@Body req: UserReq): BaseResponse<UserResp>
/**
* GET JSON 请求(查询用户)
* 参数拼 URL,响应为 JSON
*/
@GET("v1/users")
suspend fun getUserList(
@Query("page") page: Int = 1,
@Query("size") size: Int = 10
): BaseResponse<List<UserResp>>
}
4. 调用示例(ViewModel 中)
kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class UserViewModel : ViewModel() {
// 创建 ApiService 实例
private val apiService = retrofit.create(ApiService::class.java)
// 调用创建用户接口
fun createUser(username: String, password: String) {
viewModelScope.launch {
try {
val req = UserReq(username, password, "2026-03-12 10:00:00")
val response = apiService.createUser(req)
if (response.code == 200) {
// 处理成功逻辑
val user = response.data
} else {
// 业务错误
}
} catch (e: Exception) {
// 网络/解析错误
}
}
}
}
5. 注意事项
- JSON 是移动端最常用格式,优先选择;
@Body仅用于 POST/PUT/PATCH,GET 请求用@Query拼 URL;- 自定义 Gson 可解决日期格式、空值、字段重命名(
@SerializedName)等问题。
二、表单格式(Form-UrlEncoded)
1. 核心依赖
表单序列化是 Retrofit 内置功能,无需额外添加 Converter 依赖。
2. OkHttp/Retrofit 配置
仅需修改请求头为表单格式:
kotlin
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY })
// 表单专属 Content-Type
.addInterceptor { chain ->
val modifiedRequest = chain.request().newBuilder()
.header("Content-Type", "application/x-www-form-urlencoded")
.build()
chain.proceed(modifiedRequest)
}
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
// Retrofit 配置(保留 Gson Converter 解析 JSON 响应)
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create()) // 响应仍为 JSON 时保留
.build()
3. 接口定义(ApiService)
表单请求需添加 @FormUrlEncoded 注解,参数用 @Field:
kotlin
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
interface ApiService {
/**
* POST 表单请求(用户登录)
* 核心:@FormUrlEncoded + @Field
*/
@FormUrlEncoded
@POST("v1/login")
suspend fun login(
@Field("username") username: String, // 表单键值对
@Field("password") password: String,
@Field("type") type: Int = 1 // 默认值
): BaseResponse<UserResp>
/**
* GET 表单风格请求(参数拼 URL)
* 无需 @FormUrlEncoded,用 @Query 即可
*/
@GET("v1/users")
suspend fun getUserList(
@Query("page") page: Int = 1,
@Query("size") size: Int = 10
): BaseResponse<List<UserResp>>
}
4. 调用示例
kotlin
fun login(username: String, password: String) {
viewModelScope.launch {
try {
val response = apiService.login(username, password)
if (response.code == 200) {
// 登录成功
}
} catch (e: Exception) {
// 错误处理
}
}
}
5. 注意事项
- 表单适用于简单键值对参数,不支持复杂嵌套对象;
@FormUrlEncoded仅用于 POST/PUT/PATCH,GET 无需;- 若需传递数组,用
@Field("ids[]") ids: List<String>(需服务端支持)。
三、XML 格式
1. 核心依赖
需添加 XML Converter 依赖:
gradle
// XML Converter
implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'
// Simple XML 核心库(解决注解依赖)
implementation 'org.simpleframework:simple-xml:2.7.1'
2. OkHttp/Retrofit 配置
替换为 XML Converter,设置 XML 请求头:
kotlin
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY })
// XML 专属 Content-Type
.addInterceptor { chain ->
val modifiedRequest = chain.request().newBuilder()
.header("Content-Type", "application/xml;charset=utf-8")
.header("Accept", "application/xml")
.build()
chain.proceed(modifiedRequest)
}
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
// Retrofit 配置(添加 XML Converter)
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(SimpleXmlConverterFactory.create()) // XML 序列化/反序列化
.build()
3. 接口定义(ApiService)
数据类需添加 XML 注解(@Root/@Element),接口用 @Body:
kotlin
import org.simpleframework.xml.Element
import org.simpleframework.xml.Root
import retrofit2.http.Body
import retrofit2.http.POST
// XML 请求体(必须加 @Root/@Element 注解)
@Root(name = "UserReq") // 根节点名称
data class UserReqXml(
@Element(name = "Username") // 子节点名称
val username: String,
@Element(name = "Password")
val password: String
)
// XML 响应体
@Root(name = "UserResp")
data class UserRespXml(
@Element(name = "Id")
val id: String,
@Element(name = "Token")
val token: String
)
interface ApiService {
/**
* POST XML 请求(创建用户)
*/
@POST("v1/users/xml")
suspend fun createUserXml(@Body req: UserReqXml): UserRespXml
}
4. 调用示例
kotlin
fun createUserXml(username: String, password: String) {
viewModelScope.launch {
try {
val req = UserReqXml(username, password)
val response = apiService.createUserXml(req)
// 处理响应
val token = response.token
} catch (e: Exception) {
// 错误处理
}
}
}
5. 注意事项
- XML 格式较少用,主要适配传统服务端接口;
- 数据类注解必须与 XML 节点名称完全匹配;
- 若响应为 XML、请求为其他格式,可同时添加多个 Converter(按顺序生效)。
四、Protobuf 格式(高性能二进制)
1. 核心前提
Protobuf(Protocol Buffers)是 Google 开源的二进制序列化格式,体积小、解析快,适用于高性能 / 大数据场景(如物联网、游戏)。
2. 核心配置(关键:编译 Protobuf 文件)
步骤 1:添加 Protobuf 插件和依赖
gradle
// 1. 项目根目录 build.gradle 添加插件
buildscript {
dependencies {
classpath "com.google.protobuf:protobuf-gradle-plugin:0.9.4"
}
}
// 2. Module 级 build.gradle 应用插件并添加依赖
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.protobuf' // 应用 Protobuf 插件
}
dependencies {
// Protobuf 核心库
implementation 'com.google.protobuf:protobuf-java:3.25.3'
// Retrofit Protobuf Converter
implementation 'com.squareup.retrofit2:converter-protobuf:2.9.0'
}
// 3. 配置 Protobuf 编译规则(Module 级 build.gradle)
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.25.3" // 指定 protoc 编译器版本
}
// 生成 Java/Kotlin 代码
generateProtoTasks {
all().each { task ->
task.builtins {
java { option 'lite' } // 轻量级版本(适合移动端)
kotlin { option 'lite' }
}
}
}
// 指定 .proto 文件目录(默认 src/main/proto)
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
}
}
}
步骤 2:创建 .proto 文件
在 src/main/proto 目录下创建 user.proto:
protobuf
syntax = "proto3"; // 使用 proto3 语法
package com.example.protobuf; // 包名
// 用户请求体
message UserReqProto {
string username = 1; // 字段编号(不可重复)
string password = 2;
}
// 用户响应体
message UserRespProto {
string id = 1;
string token = 2;
}
步骤 3:编译生成代码
点击 Android Studio 右侧「Gradle」→ 项目 → Module → Tasks → protobuf → generateProto,自动生成 Java/Kotlin 实体类。
3. OkHttp/Retrofit 配置
kotlin
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY })
// Protobuf 专属 Content-Type
.addInterceptor { chain ->
val modifiedRequest = chain.request().newBuilder()
.header("Content-Type", "application/x-protobuf")
.header("Accept", "application/x-protobuf")
.build()
chain.proceed(modifiedRequest)
}
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
// Retrofit 配置(添加 Protobuf Converter)
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(ProtoConverterFactory.create()) // Protobuf 序列化/反序列化
.build()
4. 接口定义(ApiService)
直接使用生成的 Protobuf 实体类:
kotlin
import com.example.protobuf.UserReqProto
import com.example.protobuf.UserRespProto
import retrofit2.http.Body
import retrofit2.http.POST
interface ApiService {
/**
* POST Protobuf 请求(创建用户)
*/
@POST("v1/users/proto")
suspend fun createUserProto(@Body req: UserReqProto): UserRespProto
}
5. 调用示例
kotlin
fun createUserProto(username: String, password: String) {
viewModelScope.launch {
try {
// 构建 Protobuf 请求体
val req = UserReqProto.newBuilder()
.setUsername(username)
.setPassword(password)
.build()
val response = apiService.createUserProto(req)
// 处理响应
val token = response.token
} catch (e: Exception) {
// 错误处理
}
}
}
6. 注意事项
- Protobuf 性能最优,但开发成本高(需编写 .proto 文件);
- 需保证客户端与服务端的 .proto 文件版本一致;
- 轻量级版本(lite)更适合移动端,减少体积。
五、关键总结
表格
| 格式 | 核心依赖 | Converter Factory | Content-Type | 适用场景 |
|---|---|---|---|---|
| JSON | converter-gson | GsonConverterFactory | application/json | 移动端主流、前后端分离接口 |
| 表单 | 无(内置) | 内置 FormUrlEncodedConverter | application/x-www-form-urlencoded | 简单键值对、传统接口 |
| XML | converter-simplexml | SimpleXmlConverterFactory | application/xml | 传统服务端、第三方老旧接口 |
| Protobuf | converter-protobuf + protobuf 插件 | ProtoConverterFactory | application/x-protobuf | 高性能、大数据、物联网场景 |
核心要点
- Converter 顺序:若需同时支持多种格式(如 JSON 响应 + 表单请求),Converter 按添加顺序生效,解包拦截器需放在最前;
- Content-Type 匹配:请求头必须与格式对应,否则服务端无法解析;
- 选择原则:优先 JSON(平衡易用性和性能),简单参数用表单,高性能场景用 Protobuf,仅兼容老旧接口时用 XML。
遵循以上步骤,可快速在 OkHttp+Retrofit 框架中切换任意请求数据格式,适配不同服务端接口要求。