Square公司开源的类型安全HTTP客户端,让网络请求变得优雅而简单
JAVA开发中,网络请求是几乎所有应用的核心功能。传统的HttpURLConnection代码冗长、易错,而Retrofit的出现彻底改变了这一局面。
今天,我们将深入学习这个由Square公司开源的强大框架,从架构设计到生产实践,帮你快速掌握Retrofit的精髓。
一、为什么选择Retrofit?
声明式API定义 - 使用注解定义接口,代码简洁清晰 自动序列化 - 内置Gson、Jackson等转换器,自动处理JSON OkHttp集成 - 底层基于OkHttp,性能强大且稳定 灵活的CallAdapter - 支持RxJava、协程等异步框架 易于测试 - 接口化设计,便于Mock和单元测试与其他框架对比
特性 | Retrofit | OkHttp |
API设计 | 声明式接口 | 原始API |
学习曲线 | 低 | 高 |
扩展性 | 优秀 | 优秀 |
异步支持 | 多种方式 | 回调 |
二、核心架构解析
Retrofit采用分层架构设计,每一层职责清晰,协同完成网络请求。
整体架构
应用层(Application Layer)
定义API接口 调用网络请求方法 处理响应结果Retrofit核心层
动态代理拦截方法调用 注解解析(@GET、@POST等) 请求参数组装 响应数据转换OkHttp网络层
HTTP连接管理 请求/响应拦截器链 缓存策略 连接池复用网络传输层
TCP/IP协议通信 TLS/SSL加密 DNS解析三、快速上手:基础用法
1. 添加依赖
<dependency> <groupId>com.squareup.retrofit2</groupId> <artifactId>retrofit</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.squareup.retrofit2</groupId> <artifactId>converter-gson</artifactId> <version>2.0.2</version> </dependency>2. 定义数据模型
// 用户实体类 public class User { private int id; private String name; private String email; private String avatar; // Getter和Setter方法 public int getId() { return id; } public String getName() { return name; } public String getEmail() { return email; } } // API响应包装类 public class ApiResponse<T> { private int code; private String message; private T data; public boolean isSuccess() { return code == 200; } public T getData() { return data; } }3. 定义API接口
API定义方式
public interface UserService { // GET请求 - 查询用户信息 @GET("users/{id}") Call<ApiResponse<User>> getUser(@Path("id") int userId); // POST请求 - 创建用户 @POST("users") Call<ApiResponse<User>> createUser(@Body User user); // 带查询参数的GET请求 @GET("users") Call<ApiResponse<List<User>>> listUsers( @Query("page") int page, @Query("size") int pageSize ); // 带Header的请求 @Headers("Content-Type: application/json") @GET("users/profile") Call<ApiResponse<User>> getProfile( @Header("Authorization") String token ); // 文件上传 @Multipart @POST("upload/avatar") Call<ApiResponse<String>> uploadAvatar( @Part MultipartBody.Part file, @Part("userId") RequestBody userId ); }4. 创建Retrofit实例
public class RetrofitClient { private static final String BASE_URL = "https://api.example.com/"; private static Retrofit retrofit; // 单例模式获取Retrofit实例 public static Retrofit getInstance() { if (retrofit == null) { synchronized (RetrofitClient.class) { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(getOkHttpClient()) .addConverterFactory(GsonConverterFactory.create()) .build(); } } } return retrofit; } // 配置OkHttpClient private static OkHttpClient getOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); } // 获取API服务 public static <T> T createService(Class<T> serviceClass) { return getInstance().create(serviceClass); } }5. 发起网络请求
public class UserRepository { private final UserService userService; public UserRepository() { userService = RetrofitClient.createService(UserService.class); } // 异步请求 public void getUserAsync(int userId, final Callback<User> callback) { userService.getUser(userId).enqueue(new Callback<ApiResponse<User>>() { @Override public void onResponse(Call<ApiResponse<User>> call, Response<ApiResponse<User>> response) { if (response.isSuccessful() && response.body() != null) { ApiResponse<User> apiResponse = response.body(); if (apiResponse.isSuccess()) { callback.onSuccess(apiResponse.getData()); return; } } callback.onError(new Exception("请求失败")); } @Override public void onFailure(Call<ApiResponse<User>> call, Throwable t) { callback.onError(t); } }); } }四、深入理解:请求执行流程
请求执行流程
当我们调用API接口方法时,Retrofit内部经历以下步骤:
核心流程
步骤1:调用API方法
Call<ApiResponse<User>> call = userService.getUser(100);步骤2:动态代理拦截
Retrofit使用Java的动态代理机制拦截接口方法调用:
public <T> T create(final Class<T> service) { return (T) Proxy.newProxyInstance( service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) { // 拦截方法调用 ServiceMethod<?> serviceMethod = loadServiceMethod(method); return serviceMethod.invoke(args); } } ); }步骤3:解析方法注解
提取@GET、@POST、@Path、@Query等注解信息,构建请求参数。
步骤4:构建OkHttp请求
组装Request对象,包括URL、请求头、请求体等。
步骤5:执行网络请求
OkHttp执行实际的HTTP请求。
步骤6:响应数据转换
使用Converter将ResponseBody转换为Java对象。
步骤7:返回结果对象
通过CallAdapter包装返回结果。
五、高级特性:拦截器与转换器
拦截器链机制
拦截器链工作流程
拦截器是OkHttp的核心机制,Retrofit完美继承了这一功能。
1. Token拦截器
public class TokenInterceptor implements Interceptor { private String token; public TokenInterceptor(String token) { this.token = token; } @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); // 如果已有Authorization头,不做处理 if (originalRequest.header("Authorization") != null) { return chain.proceed(originalRequest); } // 添加Token到请求头 Request newRequest = originalRequest.newBuilder() .header("Authorization", "Bearer " + token) .build(); return chain.proceed(newRequest); } }2. 日志拦截器
public class LoggingInterceptor implements Interceptor { private static final String TAG = "OkHttp"; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // 记录请求信息 long startTime = System.nanoTime(); Log.d(TAG, String.format("发送请求: %s %s", request.method(), request.url())); // 执行请求 Response response = chain.proceed(request); // 记录响应信息 long endTime = System.nanoTime(); double duration = (endTime - startTime) / 1e6d; Log.d(TAG, String.format("收到响应: %d %s (耗时%.1fms)", response.code(), response.request().url(), duration)); return response; } }3. 配置拦截器
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new TokenInterceptor("your_token_here")) .addInterceptor(new LoggingInterceptor()) .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();数据转换器
Gson转换器
// 自定义Gson配置 Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd HH:mm:ss") .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .build();CallAdapter适配器
RxJava3适配器
// 配置Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); // 定义返回Observable的API public interface UserService { @GET("users/{id}") Observable<ApiResponse<User>> getUser(@Path("id") int userId); } // 使用RxJava userService.getUser(100) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( response -> { // 成功处理 if (response.isSuccess()) { User user = response.getData(); } }, error -> { // 错误处理 Log.e("Error", "请求失败", error); } );六、实战应用:生产级配置
时间应用场景
完整的Retrofit配置
public class NetworkModule { private static final String BASE_URL = "https://api.example.com/"; private static final int TIMEOUT = 30; // 秒 // 单例Retrofit实例 private static volatile Retrofit retrofit; public static Retrofit provideRetrofit() { if (retrofit == null) { synchronized (NetworkModule.class) { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(provideOkHttpClient()) .addConverterFactory(provideGsonConverterFactory()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); } } } return retrofit; } // 配置OkHttpClient private static OkHttpClient provideOkHttpClient() { return new OkHttpClient.Builder() // 超时配置 .connectTimeout(TIMEOUT, TimeUnit.SECONDS) .readTimeout(TIMEOUT, TimeUnit.SECONDS) .writeTimeout(TIMEOUT, TimeUnit.SECONDS) // 连接池配置 .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES)) // 拦截器配置 .addInterceptor(provideHeaderInterceptor()) .addInterceptor(provideLoggingInterceptor()) // 缓存配置 .cache(provideCache()) .build(); } // Header拦截器 private static Interceptor provideHeaderInterceptor() { return chain -> { Request original = chain.request(); Request request = original.newBuilder() .header("Content-Type", "application/json") .header("Accept", "application/json") .header("User-Agent", "Android App/1.0") .header("Authorization", "Bearer " + getToken()) .method(original.method(), original.body()) .build(); return chain.proceed(request); }; } // 日志拦截器 private static Interceptor provideLoggingInterceptor() { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE); return logging; } // 缓存配置 private static Cache provideCache() { File cacheDir = new File(getApplication().getCacheDir(), "http_cache"); int cacheSize = 10 * 1024 * 1024; // 10MB return new Cache(cacheDir, cacheSize); } // Gson配置 private static GsonConverterFactory provideGsonConverterFactory() { Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd HH:mm:ss") .setLenient() .create(); return GsonConverterFactory.create(gson); } }统一错误处理
// 统一的响应处理器 public abstract class ApiCallback<T> implements Callback<ApiResponse<T>> { @Override public void onResponse(Call<ApiResponse<T>> call, Response<ApiResponse<T>> response) { if (response.isSuccessful()) { ApiResponse<T> body = response.body(); if (body != null && body.isSuccess()) { onSuccess(body.getData()); } else { onFailure(new ApiException( body != null ? body.getCode() : -1, body != null ? body.getMessage() : "未知错误" )); } } else { onFailure(new ApiException( response.code(), "HTTP错误: " + response.code() )); } } @Override public void onFailure(Call<ApiResponse<T>> call, Throwable t) { if (t instanceof IOException) { onFailure(new ApiException(-1, "网络连接失败")); } else { onFailure(new ApiException(-1, t.getMessage())); } } protected abstract void onSuccess(T data); protected abstract void onFailure(ApiException e); } // 使用示例 userService.getUser(100).enqueue(new ApiCallback<User>() { @Override protected void onSuccess(User user) { // 处理成功结果 textView.setText(user.getName()); } @Override protected void onFailure(ApiException e) { // 统一错误处理 Toast.makeText(context, e.getMsg(), Toast.LENGTH_SHORT).show(); } });七、最佳实践
1. 单例模式管理Retrofit
❌ 错误做法: // 每次都创建新实例,浪费资源 Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build();✅ 正确做法: // 使用单例模式,全局共享 public class ApiClient { private static volatile ApiClient instance; private final Retrofit retrofit; private ApiClient() { retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .client(createOkHttpClient()) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static ApiClient getInstance() { if (instance == null) { synchronized (ApiClient.class) { if (instance == null) { instance = new ApiClient(); } } } return instance; } }2. 合理配置超时时间
OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) // 连接超时 .readTimeout(30, TimeUnit.SECONDS) // 读取超时 .writeTimeout(30, TimeUnit.SECONDS) // 写入超时 .callTimeout(60, TimeUnit.SECONDS) // 整个请求超时 .build();3. 避免主线程阻塞
// 使用异步回调 userService.getUser(100).enqueue(new Callback<ApiResponse<User>>() { @Override public void onResponse(Call<ApiResponse<User>> call, Response<ApiResponse<User>> response) { // 处理响应(已在主线程) } @Override public void onFailure(Call<ApiResponse<User>> call, Throwable t) { // 处理失败 } });Retrofit核心要点
架构清晰 - 分层设计,职责明确 使用简单 - 声明式API,注解驱动 扩展性强 - 支持自定义Converter、CallAdapter、Interceptor 性能优秀 - 基于OkHttp,连接复用,缓存支持 生态丰富 - 与RxJava、Coroutine等框架无缝集成开发建议
✅ 使用单例模式管理Retrofit实例
✅ 合理配置超时时间和连接池
✅ 统一处理错误和异常
✅ 避免主线程阻塞