在现代企业级应用和移动开发领域,Retrofit作为Square公司推出的类型安全HTTP客户端,已经成为连接RESTful API与Java/Kotlin应用的桥梁。这个基于注解的HTTP客户端库,通过将HTTP API转化为Java接口,彻底改变了传统HTTP请求的编写方式。在电商应用中,Retrofit优雅地处理商品列表和订单管理;在社交媒体平台中,它安全地传输用户动态和消息通知;在金融应用中,它严格地校验交易请求和响应格式。从接口定义到请求执行,从参数序列化到响应反序列化,从同步调用到异步回调,Retrofit都在为开发者提供着既类型安全又简洁优雅的API通信解决方案。

核心架构与设计理念

1. 注解驱动的API定义

Retrofit的核心在于使用Java注解来定义HTTP API接口,将RESTful API转换为类型安全的Java接口。

java

// 电商平台API接口定义
public interface EcommerceApiService {
    
    // 商品相关API
    @GET("api/v1/products")
    Call<ApiResponse<List<Product>>> getProducts(
        @Query("page") int page,
        @Query("size") int size,
        @Query("category") String category,
        @Query("sort") String sortBy
    );
    
    @GET("api/v1/products/{id}")
    Call<ApiResponse<Product>> getProductById(@Path("id") long productId);
    
    @GET("api/v1/products/search")
    Call<ApiResponse<List<Product>>> searchProducts(
        @Query("q") String keyword,
        @Query("page") int page,
        @Query("size") int size
    );
    
    @POST("api/v1/products")
    Call<ApiResponse<Product>> createProduct(
        @Header("Authorization") String token,
        @Body CreateProductRequest request
    );
    
    @Multipart
    @POST("api/v1/products/{id}/images")
    Call<ApiResponse<UploadResult>> uploadProductImage(
        @Path("id") long productId,
        @Part MultipartBody.Part imageFile,
        @Part("description") RequestBody description
    );
    
    // 订单相关API
    @POST("api/v1/orders")
    Call<ApiResponse<Order>> createOrder(@Body CreateOrderRequest request);
    
    @GET("api/v1/orders")
    Call<ApiResponse<PageResponse<Order>>> getOrders(
        @Query("page") int page,
        @Query("size") int size,
        @Query("status") OrderStatus status
    );
    
    @GET("api/v1/orders/{orderId}")
    Call<ApiResponse<OrderDetail>> getOrderDetail(@Path("orderId") String orderId);
    
    @PUT("api/v1/orders/{orderId}/cancel")
    Call<ApiResponse<Void>> cancelOrder(@Path("orderId") String orderId);
    
    // 用户相关API
    @POST("api/v1/auth/login")
    Call<ApiResponse<LoginResponse>> login(@Body LoginRequest request);
    
    @POST("api/v1/auth/register")
    Call<ApiResponse<RegisterResponse>> register(@Body RegisterRequest request);
    
    @GET("api/v1/users/profile")
    Call<ApiResponse<UserProfile>> getUserProfile();
    
    @PUT("api/v1/users/profile")
    Call<ApiResponse<UserProfile>> updateUserProfile(@Body UpdateProfileRequest request);
    
    // 文件上传
    @Multipart
    @POST("api/v1/users/avatar")
    Call<ApiResponse<AvatarResponse>> uploadAvatar(@Part MultipartBody.Part avatar);
    
    // 流式响应
    @Streaming
    @GET("api/v1/products/{id}/manual")
    Call<ResponseBody> downloadProductManual(@Path("id") long productId);
    
    // 动态URL
    @GET
    Call<ApiResponse<Product>> getProductByUrl(@Url String url);
    
    // 表单编码
    @FormUrlEncoded
    @POST("api/v1/feedback")
    Call<ApiResponse<Void>> submitFeedback(
        @Field("type") String type,
        @Field("content") String content,
        @Field("contact") String contact
    );
    
    // 自定义HTTP方法
    @HTTP(method = "CHECKOUT", path = "api/v1/cart/checkout", hasBody = true)
    Call<ApiResponse<CheckoutResult>> checkoutCart(@Body CheckoutRequest request);
}

// 支持RxJava的API接口
public interface RxEcommerceApiService {
    
    @GET("api/v1/products")
    Observable<ApiResponse<List<Product>>> getProducts(
        @Query("page") int page,
        @Query("size") int size
    );
    
    @GET("api/v1/products/{id}")
    Single<ApiResponse<Product>> getProductById(@Path("id") long productId);
    
    @POST("api/v1/orders")
    Completable createOrder(@Body CreateOrderRequest request);
    
    @GET("api/v1/orders/{orderId}")
    Flowable<ApiResponse<OrderDetail>> getOrderDetailStream(@Path("orderId") String orderId);
}

// 支持协程的API接口(Kotlin)
interface CoroutineEcommerceApiService {
    
    @GET("api/v1/products")
    suspend fun getProducts(
        @Query("page") page: Int,
        @Query("size") size: Int
    ): ApiResponse<List<Product>>
    
    @POST("api/v1/orders")
    suspend fun createOrder(@Body request: CreateOrderRequest): ApiResponse<Order>
    
    @GET("api/v1/orders/{orderId}")
    suspend fun getOrderDetail(@Path("orderId") orderId: String): ApiResponse<OrderDetail>
}

2. Retrofit客户端配置与构建

java

// Retrofit客户端工厂
public class RetrofitClientFactory {
    
    private static final String BASE_URL = "https://api.ecommerce.com/";
    private static volatile Retrofit instance;
    
    public static Retrofit getInstance() {
        if (instance == null) {
            synchronized (RetrofitClientFactory.class) {
                if (instance == null) {
                    instance = createRetrofit();
                }
            }
        }
        return instance;
    }
    
    private static Retrofit createRetrofit() {
        // 创建OkHttpClient
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .addInterceptor(new AuthInterceptor())
            .addInterceptor(new LoggingInterceptor())
            .addInterceptor(new RetryInterceptor(3))
            .addNetworkInterceptor(new StethoInterceptor())
            .cache(new Cache(new File("/tmp/http-cache"), 50 * 1024 * 1024))
            .build();
        
        // 创建Gson实例,配置序列化/反序列化规则
        Gson gson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
            .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
            .registerTypeAdapter(BigDecimal.class, new BigDecimalAdapter())
            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .create();
        
        // 构建Retrofit实例
        return new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addConverterFactory(ScalarsConverterFactory.create())  // 支持基本类型
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  // 支持RxJava
            .addCallAdapterFactory(CoroutineCallAdapterFactory.create())  // 支持协程
            .build();
    }
    
    // 创建API服务实例
    public static EcommerceApiService createApiService() {
        return getInstance().create(EcommerceApiService.class);
    }
    
    public static RxEcommerceApiService createRxApiService() {
        return getInstance().create(RxEcommerceApiService.class);
    }
}

// 自定义类型适配器
public class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime>, 
                                            JsonDeserializer<LocalDateTime> {
    
    private static final DateTimeFormatter FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    
    @Override
    public JsonElement serialize(LocalDateTime src, Type typeOfSrc, 
                                 JsonSerializationContext context) {
        return new JsonPrimitive(FORMATTER.format(src));
    }
    
    @Override
    public LocalDateTime deserialize(JsonElement json, Type typeOfT, 
                                     JsonDeserializationContext context) 
                                     throws JsonParseException {
        return LocalDateTime.parse(json.getAsString(), FORMATTER);
    }
}

public class BigDecimalAdapter implements JsonSerializer<BigDecimal>, 
                                          JsonDeserializer<BigDecimal> {
    
    @Override
    public JsonElement serialize(BigDecimal src, Type typeOfSrc, 
                                 JsonSerializationContext context) {
        return new JsonPrimitive(src.setScale(2, RoundingMode.HALF_UP).toString());
    }
    
    @Override
    public BigDecimal deserialize(JsonElement json, Type typeOfT, 
                                  JsonDeserializationContext context) 
                                  throws JsonParseException {
        try {
            return new BigDecimal(json.getAsString());
        } catch (NumberFormatException e) {
            throw new JsonParseException("Invalid BigDecimal format", e);
        }
    }
}

高级特性与应用

1. 自定义转换器与适配器

java

// 自定义ConverterFactory - 支持Protobuf
public class ProtobufConverterFactory extends Converter.Factory {
    
    private static final MediaType PROTOBUF = MediaType.parse("application/x-protobuf");
    
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(
            Type type, Annotation[] annotations, Retrofit retrofit) {
        
        if (!(type instanceof Class)) {
            return null;
        }
        
        Class<?> clazz = (Class<?>) type;
        if (!Message.class.isAssignableFrom(clazz)) {
            return null;
        }
        
        return (Converter<ResponseBody, ?>) responseBody -> {
            try {
                Message.Builder builder = getBuilderForType(clazz);
                builder.mergeFrom(responseBody.byteStream());
                return builder.build();
            } catch (IOException e) {
                throw new RuntimeException("Failed to parse protobuf", e);
            }
        };
    }
    
    @Override
    public Converter<?, RequestBody> requestBodyConverter(
            Type type, Annotation[] parameterAnnotations, 
            Annotation[] methodAnnotations, Retrofit retrofit) {
        
        if (!(type instanceof Class)) {
            return null;
        }
        
        Class<?> clazz = (Class<?>) type;
        if (!Message.class.isAssignableFrom(clazz)) {
            return null;
        }
        
        return (Converter<Message, RequestBody>) value -> 
            RequestBody.create(PROTOBUF, value.toByteArray());
    }
    
    private Message.Builder getBuilderForType(Class<?> clazz) {
        try {
            Method method = clazz.getMethod("newBuilder");
            return (Message.Builder) method.invoke(null);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create builder", e);
        }
    }
}

// 自定义CallAdapter - 支持LiveData
public class LiveDataCallAdapterFactory extends CallAdapter.Factory {
    
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != LiveData.class) {
            return null;
        }
        
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        Class<?> rawObservableType = getRawType(observableType);
        
        if (rawObservableType != ApiResponse.class) {
            throw new IllegalArgumentException("LiveData type must be ApiResponse");
        }
        
        Type bodyType = getParameterUpperBound(0, (ParameterizedType) observableType);
        return new LiveDataCallAdapter<>(bodyType);
    }
    
    private static class LiveDataCallAdapter<R> implements CallAdapter<R, LiveData<ApiResponse<R>>> {
        
        private final Type responseType;
        
        LiveDataCallAdapter(Type responseType) {
            this.responseType = responseType;
        }
        
        @Override
        public Type responseType() {
            return responseType;
        }
        
        @Override
        public LiveData<ApiResponse<R>> adapt(Call<R> call) {
            return new LiveData<ApiResponse<R>>() {
                @Override
                protected void onActive() {
                    super.onActive();
                    call.enqueue(new Callback<R>() {
                        @Override
                        public void onResponse(Call<R> call, Response<R> response) {
                            if (response.isSuccessful()) {
                                postValue(ApiResponse.success(response.body()));
                            } else {
                                postValue(ApiResponse.error(response.code(), 
                                    response.message()));
                            }
                        }
                        
                        @Override
                        public void onFailure(Call<R> call, Throwable t) {
                            postValue(ApiResponse.error(t));
                        }
                    });
                }
            };
        }
    }
}

// 自定义注解处理器 - 请求头注入
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicHeader {
    String value();
}

public class DynamicHeaderConverterFactory extends Converter.Factory {
    
    @Override
    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, 
                                                Retrofit retrofit) {
        for (Annotation annotation : annotations) {
            if (annotation instanceof DynamicHeader) {
                return new DynamicHeaderConverter((DynamicHeader) annotation);
            }
        }
        return null;
    }
    
    private static class DynamicHeaderConverter implements Converter<Object, String> {
        
        private final DynamicHeader annotation;
        
        DynamicHeaderConverter(DynamicHeader annotation) {
            this.annotation = annotation;
        }
        
        @Override
        public String convert(Object value) throws IOException {
            // 根据业务逻辑动态生成请求头值
            return generateHeaderValue(annotation.value(), value);
        }
        
        private String generateHeaderValue(String headerName, Object value) {
            switch (headerName) {
                case "X-User-Id":
                    return String.valueOf(((User) value).getId());
                case "X-Device-Info":
                    return ((DeviceInfo) value).toString();
                case "X-Timestamp":
                    return String.valueOf(System.currentTimeMillis());
                default:
                    return value.toString();
            }
        }
    }
}

2. 错误处理与响应包装

java

// 统一的API响应包装类
public class ApiResponse<T> {
    
    private final T data;
    private final String message;
    private final int code;
    private final boolean success;
    private final long timestamp;
    
    public ApiResponse(T data, String message, int code, boolean success) {
        this.data = data;
        this.message = message;
        this.code = code;
        this.success = success;
        this.timestamp = System.currentTimeMillis();
    }
    
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(data, "Success", 200, true);
    }
    
    public static <T> ApiResponse<T> error(int code, String message) {
        return new ApiResponse<>(null, message, code, false);
    }
    
    public static <T> ApiResponse<T> error(Throwable throwable) {
        return new ApiResponse<>(null, throwable.getMessage(), 500, false);
    }
    
    // Getter方法
    public T getData() { return data; }
    public String getMessage() { return message; }
    public int getCode() { return code; }
    public boolean isSuccess() { return success; }
    public long getTimestamp() { return timestamp; }
    
    // 辅助方法
    public T getDataOrThrow() {
        if (!success) {
            throw new ApiException(code, message);
        }
        return data;
    }
    
    public Optional<T> getDataOptional() {
        return Optional.ofNullable(data);
    }
}

// 自定义响应转换器 - 处理统一的API响应格式
public class ApiResponseConverter<T> implements Converter<ResponseBody, ApiResponse<T>> {
    
    private final Gson gson;
    private final Type type;
    
    public ApiResponseConverter(Gson gson, Type type) {
        this.gson = gson;
        this.type = type;
    }
    
    @Override
    public ApiResponse<T> convert(ResponseBody value) throws IOException {
        try {
            String json = value.string();
            
            // 解析为JsonObject
            JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
            
            // 提取公共字段
            boolean success = jsonObject.get("success").getAsBoolean();
            int code = jsonObject.get("code").getAsInt();
            String message = jsonObject.get("message").getAsString();
            long timestamp = jsonObject.get("timestamp").getAsLong();
            
            // 提取数据字段
            JsonElement dataElement = jsonObject.get("data");
            T data = null;
            
            if (dataElement != null && !dataElement.isJsonNull()) {
                data = gson.fromJson(dataElement, type);
            }
            
            return new ApiResponse<>(data, message, code, success);
            
        } catch (JsonSyntaxException e) {
            throw new IOException("Failed to parse API response", e);
        } finally {
            value.close();
        }
    }
}

// 自定义ConverterFactory - 包装ApiResponse
public class ApiResponseConverterFactory extends Converter.Factory {
    
    private final Gson gson;
    
    public ApiResponseConverterFactory(Gson gson) {
        this.gson = gson;
    }
    
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(
            Type type, Annotation[] annotations, Retrofit retrofit) {
        
        // 检查是否是ApiResponse类型
        if (getRawType(type) != ApiResponse.class) {
            return null;
        }
        
        // 获取ApiResponse的泛型参数
        Type responseType = getParameterUpperBound(0, (ParameterizedType) type);
        
        return new ApiResponseConverter<>(gson, responseType);
    }
}

// 全局异常处理器
public class RetrofitExceptionHandler {
    
    public static <T> Single<T> handleObservableError(Observable<T> observable) {
        return observable
            .onErrorResumeNext(throwable -> {
                if (throwable instanceof HttpException) {
                    HttpException httpException = (HttpException) throwable;
                    int code = httpException.code();
                    String message = httpException.message();
                    
                    return Single.error(new ApiException(code, message));
                    
                } else if (throwable instanceof SocketTimeoutException) {
                    return Single.error(new NetworkException("连接超时", throwable));
                    
                } else if (throwable instanceof ConnectException) {
                    return Single.error(new NetworkException("网络连接失败", throwable));
                    
                } else if (throwable instanceof IOException) {
                    return Single.error(new NetworkException("网络异常", throwable));
                    
                } else {
                    return Single.error(new ApiException(500, "系统异常", throwable));
                }
            })
            .singleOrError();
    }
    
    public static <T> Callback<T> createCallback(
            Consumer<T> onSuccess, 
            Consumer<Throwable> onError) {
        
        return new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, Response<T> response) {
                if (response.isSuccessful()) {
                    onSuccess.accept(response.body());
                } else {
                    onError.accept(new ApiException(
                        response.code(), 
                        response.message()
                    ));
                }
            }
            
            @Override
            public void onFailure(Call<T> call, Throwable t) {
                onError.accept(translateException(t));
            }
        };
    }
    
    private static Throwable translateException(Throwable throwable) {
        if (throwable instanceof HttpException) {
            HttpException httpException = (HttpException) throwable;
            return new ApiException(httpException.code(), httpException.message());
        }
        
        if (throwable instanceof SocketTimeoutException) {
            return new NetworkException("请求超时", throwable);
        }
        
        if (throwable instanceof ConnectException) {
            return new NetworkException("网络不可用", throwable);
        }
        
        if (throwable instanceof IOException) {
            return new NetworkException("网络错误", throwable);
        }
        
        return new ApiException(500, "未知错误", throwable);
    }
}

实战案例:电商平台API客户端

下面通过一个完整的电商平台案例,展示Retrofit在复杂业务场景中的应用。

java

// 电商平台API客户端服务
public class EcommerceApiClient {
    
    private final EcommerceApiService apiService;
    private final RxEcommerceApiService rxApiService;
    private final AuthManager authManager;
    private final CacheManager cacheManager;
    
    public EcommerceApiClient() {
        Retrofit retrofit = RetrofitClientFactory.getInstance();
        this.apiService = retrofit.create(EcommerceApiService.class);
        this.rxApiService = retrofit.create(RxEcommerceApiService.class);
        this.authManager = AuthManager.getInstance();
        this.cacheManager = CacheManager.getInstance();
    }
    
    // 商品服务
    public Single<List<Product>> getProducts(int page, int size, String category) {
        return rxApiService.getProducts(page, size, category)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(products -> cacheManager.cacheProducts(products));
    }
    
    public Single<Product> getProductById(long productId) {
        // 先尝试从缓存获取
        Product cached = cacheManager.getCachedProduct(productId);
        if (cached != null) {
            return Single.just(cached);
        }
        
        return rxApiService.getProductById(productId)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(product -> cacheManager.cacheProduct(product));
    }
    
    public Single<List<Product>> searchProducts(String keyword, int page) {
        return rxApiService.searchProducts(keyword, page)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
    
    public Completable createProduct(CreateProductRequest request) {
        String token = authManager.getAccessToken();
        if (token == null) {
            return Completable.error(new UnauthorizedException("需要登录"));
        }
        
        return rxApiService.createProduct(token, request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .ignoreElement();
    }
    
    public Single<UploadResult> uploadProductImage(long productId, File imageFile, String description) {
        // 创建MultipartBody.Part
        RequestBody requestFile = RequestBody.create(
            imageFile, MediaType.parse("image/*"));
        MultipartBody.Part body = MultipartBody.Part.createFormData(
            "image", imageFile.getName(), requestFile);
        
        RequestBody descriptionBody = RequestBody.create(
            description, MediaType.parse("text/plain"));
        
        return rxApiService.uploadProductImage(productId, body, descriptionBody)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
    
    // 订单服务
    public Single<Order> createOrder(CreateOrderRequest request) {
        return rxApiService.createOrder(request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(order -> {
                // 发送订单创建事件
                EventBus.getDefault().post(new OrderCreatedEvent(order));
            });
    }
    
    public Single<PageResponse<Order>> getOrders(int page, int size, OrderStatus status) {
        return rxApiService.getOrders(page, size, status)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
    
    public Flowable<OrderDetail> getOrderDetailStream(String orderId) {
        return rxApiService.getOrderDetailStream(orderId)
            .map(ApiResponse::getDataOrThrow)
            .onErrorResumeNext(throwable -> {
                // 优雅处理错误
                return Flowable.error(translateException(throwable));
            });
    }
    
    public Completable cancelOrder(String orderId) {
        return rxApiService.cancelOrder(orderId)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .ignoreElement();
    }
    
    // 用户服务
    public Single<LoginResponse> login(String username, String password) {
        LoginRequest request = new LoginRequest(username, password);
        
        return rxApiService.login(request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(loginResponse -> {
                // 保存认证信息
                authManager.saveAuthInfo(loginResponse);
            });
    }
    
    public Single<RegisterResponse> register(RegisterRequest request) {
        return rxApiService.register(request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
    
    public Single<UserProfile> getUserProfile() {
        return rxApiService.getUserProfile()
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(profile -> cacheManager.cacheUserProfile(profile));
    }
    
    public Single<UserProfile> updateUserProfile(UpdateProfileRequest request) {
        return rxApiService.updateUserProfile(request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(profile -> {
                cacheManager.cacheUserProfile(profile);
                // 发送资料更新事件
                EventBus.getDefault().post(new ProfileUpdatedEvent(profile));
            });
    }
    
    public Single<AvatarResponse> uploadAvatar(File avatarFile) {
        // 创建MultipartBody.Part
        RequestBody requestFile = RequestBody.create(
            avatarFile, MediaType.parse("image/*"));
        MultipartBody.Part body = MultipartBody.Part.createFormData(
            "avatar", avatarFile.getName(), requestFile);
        
        return rxApiService.uploadAvatar(body)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .doOnSuccess(avatarResponse -> {
                // 更新本地用户头像
                cacheManager.updateUserAvatar(avatarResponse.getAvatarUrl());
            });
    }
    
    // 批量操作
    public Observable<BatchResult> batchCreateProducts(List<CreateProductRequest> requests) {
        return Observable.fromIterable(requests)
            .flatMap(request -> rxApiService.createProduct(
                authManager.getAccessToken(), request)
                .toObservable()
                .map(ApiResponse::getDataOrThrow)
                .map(product -> new BatchResult(product.getId(), true, null))
                .onErrorReturn(throwable -> 
                    new BatchResult(null, false, throwable.getMessage())),
                5) // 并发数限制
            .buffer(10) // 每10个结果打包一次
            .flatMap(results -> Observable.fromIterable(results));
    }
    
    // 复杂的组合操作
    public Single<CheckoutResult> checkoutWithValidation(ShoppingCart cart) {
        // 1. 验证购物车
        return validateCart(cart)
            .flatMap(valid -> {
                if (!valid) {
                    return Single.error(new ValidationException("购物车验证失败"));
                }
                
                // 2. 检查库存
                return checkInventory(cart.getItems())
                    .flatMap(inStock -> {
                        if (!inStock) {
                            return Single.error(new InventoryException("库存不足"));
                        }
                        
                        // 3. 创建订单
                        CreateOrderRequest request = CreateOrderRequest.fromCart(cart);
                        return createOrder(request)
                            .flatMap(order -> {
                                // 4. 处理支付
                                return processPayment(order)
                                    .flatMap(paymentResult -> {
                                        // 5. 发送确认邮件
                                        return sendConfirmationEmail(order, paymentResult)
                                            .map(success -> new CheckoutResult(
                                                order, paymentResult, success));
                                    });
                            });
                    });
            });
    }
    
    private Single<Boolean> validateCart(ShoppingCart cart) {
        // 调用验证API
        return rxApiService.get("api/v1/cart/validate")
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .map(ValidationResponse::isValid);
    }
    
    private Single<Boolean> checkInventory(List<CartItem> items) {
        List<Single<Boolean>> checks = items.stream()
            .map(item -> checkItemInventory(item.getProductId(), item.getQuantity()))
            .collect(Collectors.toList());
        
        return Single.zip(checks, results -> 
            Arrays.stream(results)
                .allMatch(result -> (Boolean) result))
            .flatMap(allInStock -> Single.just(allInStock));
    }
    
    private Single<Boolean> checkItemInventory(long productId, int quantity) {
        return getProductById(productId)
            .map(product -> product.getStock() >= quantity);
    }
    
    private Single<PaymentResult> processPayment(Order order) {
        PaymentRequest request = new PaymentRequest(
            order.getId(), order.getTotalAmount(), order.getPaymentMethod());
        
        return rxApiService.post("api/v1/payments/process", request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
    
    private Single<Boolean> sendConfirmationEmail(Order order, PaymentResult paymentResult) {
        ConfirmationEmailRequest request = new ConfirmationEmailRequest(
            order, paymentResult.getTransactionId());
        
        return rxApiService.post("api/v1/notifications/order-confirmation", request)
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow)
            .map(EmailResponse::isSuccess);
    }
    
    // 响应式编程组合
    public Flowable<Product> getProductsWithRealTimeUpdates() {
        // 1. 获取初始产品列表
        return getProducts(1, 20, null)
            .flattenAsObservable(list -> list)
            .mergeWith(
                // 2. 合并实时更新流
                rxApiService.getOrderDetailStream("dummy") // WebSocket流
                    .ofType(ProductUpdateEvent.class)
                    .map(ProductUpdateEvent::getProduct)
            )
            .distinct(Product::getId) // 去重
            .filter(product -> product.isAvailable()) // 过滤可用商品
            .onBackpressureBuffer(1000); // 背压处理
    }
    
    // 协程版本(Kotlin)
    suspend fun getProductsCoroutine(page: Int, size: Int): List<Product> {
        return withContext(Dispatchers.IO) {
            try {
                val response = apiService.getProducts(page, size)
                if (response.isSuccessful) {
                    response.body()?.data ?: emptyList()
                } else {
                    throw ApiException(response.code(), response.message())
                }
            } catch (e: IOException) {
                throw NetworkException("网络错误", e)
            }
        }
    }
    
    // 错误重试与回退机制
    public Single<List<Product>> getProductsWithRetry(int page, int size) {
        return rxApiService.getProducts(page, size)
            .retryWhen(errors -> errors
                .zipWith(Observable.range(1, 3), (error, retryCount) -> {
                    if (retryCount == 3) {
                        throw error;
                    }
                    return retryCount;
                })
                .flatMap(retryCount -> 
                    Observable.timer((long) Math.pow(2.0, retryCount), TimeUnit.SECONDS))
            )
            .onErrorResumeNext(throwable -> {
                // 错误回退:从缓存获取
                List<Product> cached = cacheManager.getCachedProducts();
                if (!cached.isEmpty()) {
                    return Single.just(ApiResponse.success(cached));
                }
                return Single.error(throwable);
            })
            .compose(RetrofitExceptionHandler::handleObservableError)
            .map(ApiResponse::getDataOrThrow);
    }
}

// 请求/响应模型类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Product {
    private Long id;
    private String name;
    private String description;
    private BigDecimal price;
    private Integer stock;
    private String category;
    private List<String> images;
    private Double rating;
    private Integer reviewCount;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    private boolean available;
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CreateProductRequest {
    @NotBlank(message = "商品名称不能为空")
    private String name;
    
    @Size(max = 1000, message = "描述不能超过1000字")
    private String description;
    
    @DecimalMin(value = "0.01", message = "价格必须大于0")
    private BigDecimal price;
    
    @Min(value = 0, message = "库存不能为负数")
    private Integer stock;
    
    @NotBlank(message = "分类不能为空")
    private String category;
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Order {
    private String id;
    private Long userId;
    private List<OrderItem> items;
    private BigDecimal totalAmount;
    private OrderStatus status;
    private String shippingAddress;
    private String paymentMethod;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

// 自定义注解 - 缓存控制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
    int maxAge() default 60; // 秒
    boolean mustRevalidate() default false;
    CacheStrategy strategy() default CacheStrategy.NETWORK_FIRST;
    
    enum CacheStrategy {
        NETWORK_FIRST,
        CACHE_FIRST,
        CACHE_ONLY,
        NETWORK_ONLY
    }
}

// 缓存拦截器
public class CacheInterceptor implements Interceptor {
    
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        
        // 检查是否有缓存注解
        CacheControl cacheControl = getCacheControlAnnotation(request);
        if (cacheControl == null) {
            return chain.proceed(request);
        }
        
        // 根据策略处理缓存
        switch (cacheControl.strategy()) {
            case NETWORK_FIRST:
                return handleNetworkFirst(request, chain, cacheControl);
            case CACHE_FIRST:
                return handleCacheFirst(request, chain, cacheControl);
            case CACHE_ONLY:
                return handleCacheOnly(request, chain);
            case NETWORK_ONLY:
            default:
                return chain.proceed(request);
        }
    }
    
    private Response handleNetworkFirst(Request request, Chain chain, CacheControl cacheControl) 
            throws IOException {
        try {
            Response response = chain.proceed(request);
            
            // 缓存成功响应
            if (response.isSuccessful()) {
                Response cachedResponse = response.newBuilder()
                    .header("Cache-Control", 
                        "public, max-age=" + cacheControl.maxAge() +
                        (cacheControl.mustRevalidate() ? ", must-revalidate" : ""))
                    .build();
                return cachedResponse;
            }
            
            return response;
            
        } catch (IOException e) {
            // 网络失败时尝试从缓存获取
            Response cachedResponse = getCachedResponse(request);
            if (cachedResponse != null) {
                return cachedResponse;
            }
            throw e;
        }
    }
    
    // 其他缓存策略实现...
}

Retrofit的真正革命性在于它将HTTP API从繁琐的请求构建和响应解析中解放出来,通过类型安全的接口定义和注解驱动的配置,让API调用变得既简单又可靠。其灵活的设计允许开发者通过自定义转换器、适配器和拦截器来扩展功能,满足各种复杂场景的需求。特别是在结合RxJava、协程等响应式编程框架时,Retrofit能够构建出优雅且强大的异步数据流。

然而,Retrofit的强大也需要合理的架构设计来支撑。在实际项目中,应该建立统一的错误处理机制、合理的缓存策略、完善的认证授权流程。通过合理的分层和封装,可以让Retrofit在保持简洁性的同时,也能够应对企业级应用的复杂需求。

看完这篇文章,你是否在项目中使用Retrofit构建过复杂的API客户端?或者你在Retrofit与响应式编程结合方面有什么独特的经验?欢迎在评论区分享你的Retrofit实战心得,也欢迎提出关于RESTful API设计和技术栈选型的任何技术问题,让我们一起探讨如何更好地构建现代化、类型安全的API通信体系!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐