retrofit通过拦截器修改body内容后报错:java.io.ioexception: id1id2: actual 0x00007b22 != expected 0x00001f8b

本文探讨了在项目开发中如何使用RSA对接口数据进行加密传输,并处理服务器返回内容的解密问题。重点讲述了Content-Encoding、响应体格式调整、字符编码乱码及FormUrlEncoded注解对中文的影响,提供了相应的解决方法和注意事项。

项目开发中有个需求,将所有接口的值都通过RSA加密传输,服务端返回的所有内容也都需要通过RSA解密后再使用。

参考这篇文章可以实现功能:https://blog.youkuaiyun.com/yuzhiqiang_1993/article/details/90168515

但是在实现功能之后,替换原有response的body之后,接口从onError返回,没有正确的解析成实体类,返回错误信息就如标题中所写。

因为retrofit在数据返回的时候,可能会对数据包进行压缩传输,到客户端在解密:

//读取服务器返回的结果
ResponseBody responseBody = response.newBuilder().build().body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
//获取content的压缩类型
String encoding = response.headers().get("Content-Encoding");
Charset charset = Charset.forName("UTF-8");
MediaType contentType = responseBody.contentType();
if (contentType != null) {
    charset = contentType.charset(charset);
}
Buffer clone = buffer.clone();
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {//content 使用 gzip 压缩
  return ZipHelper.decompre
<think>我们正在解决Retrofit2集成RxJava3时出现的`java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Flowable<okhttp3.ResponseBody>`错误。根据引用[1][2][3]的信息,这个错误通常是因为Retrofit没有找到合适的Call Adapter来将HTTP调用适配到RxJava3的类型(如Flowable, Observable等)。要解决这个问题,我们需要为Retrofit添加一个RxJava3的Call Adapter Factory。 具体步骤: 1. 确保在项目的build.gradle文件中添加了RxJava3和Retrofit的依赖,以及专门为RxJava3设计的Retrofit适配器。 2. 在创建Retrofit实例时,添加`RxJava3CallAdapterFactory`作为Call Adapter Factory。 详细操作如下: 第一步:添加依赖 在app模块的build.gradle文件中,添加以下依赖(注意版本号,这里以写作时的最新稳定版本为例): ```groovy dependencies { // Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' // RxJava3 implementation 'io.reactivex.rxjava3:rxjava:3.0.0' implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' // 如果是Android项目 // Retrofit的RxJava3适配器 implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0' } ``` 第二步:在创建Retrofit实例时添加Call Adapter Factory 在代码中创建Retrofit实例时,需要添加`RxJava3CallAdapterFactory`: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) // 用于JSON转换 .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) // 添加RxJava3适配器 .build(); ``` 注意:如果你同时使用了多个Call Adapter(例如,同时使用RxJava和LiveData),那么添加多个`addCallAdapterFactory`调用即可。 第三步:确保你的接口方法返回类型是RxJava3的类型 例如,返回类型可以是`Flowable<ResponseBody>`、`Observable<ResponseBody>`等: ```java public interface ApiService { @GET("data") Flowable<ResponseBody> getData(); } ``` 如果按照以上步骤操作,应该就能解决该错误。 如果仍然出现同样的错误,请检查: 1. 依赖版本是否冲突:确保所有的Retrofit相关依赖(包括converter和adapter)版本兼容。通常建议使用相同的大版本。 2. 是否错误添加了RxJava2的适配器:确保添加的是`RxJava3CallAdapterFactory`而不是RxJava2的适配器。 3. 清理并重新构建项目:有时候Gradle的依赖可能没有正确更新,尝试清理项目(Build -> Clean Project)并重新构建。 引用[2]中提到,如果使用RxJava2,需要添加`adapter-rxjava2`,同理,对于RxJava3,我们需要的是`adapter-rxjava3`(依赖是`com.squareup.retrofit2:adapter-rxjava3`)。引用[3]中提到的`retrofit2-rxjava2-adapter`是第三方适配器,而官方已经提供了适配器,所以直接使用官方的即可。 因此,解决这个问题的关键就是添加正确的Call Adapter Factory。 相关问题: 1. 如何为Retrofit添加多个Call Adapter Factory? 2. Retrofit中如何处理RxJava3的错误? 3. 如何将RxJava2项目迁移到RxJava3? </think>### 解决 Retrofit2 集成 RxJava3 的 Call Adapter 错误 出现 `java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Flowable<okhttp3.ResponseBody>` 错误的原因是 Retrofit 无法识别 RxJava3 的类型。以下是完整的解决方案: --- #### 1. **添加正确的依赖库(关键步骤)** 在 `build.gradle` 文件中添加 **RxJava3 专用适配器**: ```groovy dependencies { // Retrofit 基础库 implementation 'com.squareup.retrofit2:retrofit:2.9.0' // RxJava3 核心库 implementation 'io.reactivex.rxjava3:rxjava:3.1.6' // RxJava3 的 Retrofit 适配器(必须添加) implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0' // 可选:JSON 转换器 implementation 'com.squareup.retrofit2:converter-gson:2.9.0' } ``` > ⚠️ **常见错误**: > - 错误使用 RxJava2 适配器(`adapter-rxjava2`) > - 遗漏 RxJava3 适配器(`adapter-rxjava3`)[^1][^2][^3] --- #### 2. **配置 Retrofit 实例** 在代码中初始化 Retrofit 时,必须声明 `RxJava3CallAdapterFactory`: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) // JSON 转换 .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) // 关键:添加 RxJava3 适配器 .build(); ``` --- #### 3. **检查接口定义** 确保接口方法的返回类型与 RxJava3 类型完全匹配: ```java public interface ApiService { // ✅ 正确:使用 io.reactivex.rxjava3 开头的类型 @GET("data") Flowable<ResponseBody> getDataRx3(); // RxJava3 的 Flowable // ❌ 错误:使用旧版 rx.* 或 io.reactivex(无 rxjava3) @GET("data") rx.Observable<ResponseBody> getDataRx1(); // RxJava1 类型 } ``` --- #### 4. **依赖冲突排查** 检查是否存在版本冲突: ```bash ./gradlew app:dependencies ``` 重点关注: ``` | +--- com.squareup.retrofit2:adapter-rxjava3:2.9.0 | | +--- com.squareup.retrofit2:retrofit:2.9.0 | | \--- io.reactivex.rxjava3:rxjava:3.0.0 -> 3.1.6 ``` 确保所有 RxJava 相关依赖均来自 `io.reactivex.rxjava3` 命名空间。 --- #### 5. **清理与重建项目** 如果问题依旧,执行以下操作: 1. 清理构建缓存:`File > Invalidate Caches / Restart` 2. 删除 `build` 目录 3. 重新同步 Gradle --- ### 总结问题原因 | 问题原因 | 解决方案 | |---------|----------| | 遗漏 `adapter-rxjava3` 依赖 | 添加 `implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'` | | 使用 RxJava2 适配器 | 替换为 `RxJava3CallAdapterFactory` | | 类型路径错误 | 使用 `io.reactivex.rxjava3.core.Flowable` | | 依赖冲突 | 统一 Retrofit/RxJava3 版本 | > ✅ 正确配置后,Retrofit 将能正确识别 RxJava3 的 `Flowable` / `Observable` 类型[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值