如何优雅实现网络请求全局加解密与参数配置:RxHttp高级实战指南
RxHttp是一款基于OkHttp封装的强大网络请求库,支持Kotlin Coroutines、RxJava2和RxJava3,让开发者能在30秒内快速上手。本文将深入探讨如何利用RxHttp实现全局请求加解密、统一参数配置等高级功能,帮助你构建更安全、更易维护的网络层架构。
🚀 为什么选择RxHttp处理全局配置?
在移动应用开发中,我们经常需要处理以下通用网络需求:
- 统一的请求参数(如Token、设备信息)
- 请求/响应数据加解密
- 全局异常处理
- 网络缓存策略
RxHttp通过灵活的拦截器机制和转换器设计,让这些需求的实现变得简单高效。其核心优势在于:
- 低侵入性:无需修改原有请求代码
- 高可扩展性:支持自定义拦截器和转换器
- 与协程/RxJava无缝集成:完美适配现代异步编程模式
🔒 实现全局请求参数统一配置
拦截器方案:TokenInterceptor实现
RxHttp通过拦截器机制支持全局参数添加,最常见的应用场景是添加认证Token。项目中已提供TokenInterceptor的实现:
// app/src/main/java/com/example/httpsender/interceptor/TokenInterceptor.java
public class TokenInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
// 添加Token等全局参数
Request newRequest = originalRequest.newBuilder()
.header("Authorization", "Bearer " + getToken())
.build();
return chain.proceed(newRequest);
}
}
配置拦截器到RxHttp
在RxHttpManager中注册拦截器:
// app/src/main/java/com/example/httpsender/RxHttpManager.java
RxHttp.init(getOkHttpClient())
.setDebug(true)
.addInterceptor(new TokenInterceptor()) // 添加全局拦截器
.setOnParamAssembly(p -> {
// 添加全局查询参数
p.add("app_version", BuildConfig.VERSION_NAME)
.add("device_id", DeviceUtils.getUniqueDeviceId());
});
🛡️ 请求与响应数据加解密实现
自定义参数加密:PostEncryptJsonParam
RxHttp支持自定义参数处理器,实现请求数据加密。项目中提供了PostEncryptJsonParam示例:
// app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam.kt
class PostEncryptJsonParam(
url: String,
private val encrypt: Boolean = true
) : JsonParam(url, Method.POST) {
override fun add(key: String, value: Any?): PostEncryptJsonParam {
super.add(key, value)
return this
}
override fun encodeParams(): String {
val json = super.encodeParams()
return if (encrypt) EncryptUtils.encrypt(json) else json
}
}
响应数据解密:自定义ResponseParser
响应解密可以通过自定义ResponseParser实现:
// app/src/main/java/com/example/httpsender/parser/ResponseParser.kt
open class ResponseParser<T> : TypeParser<T> {
override suspend fun onParse(response: okhttp3.Response): T {
val responseBody = response.body?.string() ?: throw ParseException("response body is null")
// 解密逻辑
val decryptedBody = decrypt(responseBody)
// 解析解密后的数据
return parseData(decryptedBody, response)
}
private fun decrypt(encryptedData: String): String {
// 实现解密算法
return EncryptUtils.decrypt(encryptedData)
}
}
在实际请求中使用自定义解析器:
rxHttp<ArticleList>()
.postEncryptJson("/article/list")
.add("page", 1)
.add("count", 20)
.asParser(ResponseParser<ArticleList>()) // 使用自定义解密解析器
.toFlow()
.catch { handleError(it) }
.collect { updateUI(it) }
📝 全局异常处理策略
统一错误处理:ExceptionHelper
RxHttp提供了全局异常处理机制,项目中通过ExceptionHelper实现:
// app/src/main/java/com/example/httpsender/ExceptionHelper.java
public class ExceptionHelper {
public static String getErrorMessage(Throwable e) {
if (e instanceof HttpStatusCodeException) {
int code = ((HttpStatusCodeException) e).getStatusCode();
return "HTTP错误: " + code + " " + getStatusCodeMessage(code);
} else if (e instanceof ParseException) {
return "数据解析失败: " + e.getMessage();
} else if (e instanceof IOException) {
return "网络异常,请检查网络连接";
} else {
return "未知错误: " + e.getMessage();
}
}
private static String getStatusCodeMessage(int code) {
// 根据状态码返回具体错误信息
return when (code) {
401 -> "未授权,请重新登录";
403 -> "拒绝访问";
404 -> "请求资源不存在";
500 -> "服务器内部错误";
else -> "请求失败";
};
}
}
在BaseFragment中统一处理异常:
// app/src/main/java/com/example/httpsender/fragment/BaseFragment.kt
abstract class BaseFragment<T : ViewDataBinding> : Fragment() {
protected val viewModel by viewModels<MyViewModel>()
protected fun <T> handleException(flow: Flow<T>): Flow<T> {
return flow.catch { e ->
val errorMsg = ExceptionHelper.getErrorMessage(e)
showToast(errorMsg)
// 错误上报逻辑
viewModel.reportError(e)
}
}
protected fun showToast(message: String) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
}
}
💻 实际应用示例:AwaitFragment
在具体业务场景中使用上述功能,以AwaitFragment为例:
// app/src/main/java/com/example/httpsender/fragment/AwaitFragment.kt
class AwaitFragment : BaseFragment<AwaitFragmentBinding>(), View.OnClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnGetArticle.setOnClickListener(this)
}
override fun onClick(v: View) {
when (v.id) {
R.id.btnGetArticle -> getArticleList()
}
}
private fun getArticleList() = lifecycleScope.launch {
binding.progressBar.visibility = View.VISIBLE
try {
val result = rxHttp<ArticleList>()
.postEncryptJson("/article/list") // 使用加密参数
.add("page", 1)
.add("count", 20)
.asParser(ResponseParser<ArticleList>()) // 使用解密解析器
.await() // 协程支持
binding.tvResult.text = JsonUtils.toJson(result)
} catch (e: Exception) {
val errorMsg = ExceptionHelper.getErrorMessage(e)
binding.tvResult.text = errorMsg
} finally {
binding.progressBar.visibility = View.GONE
}
}
}
🎯 高级配置最佳实践
1. 多环境配置管理
通过RxHttpPlugins实现不同环境切换:
// 根据构建类型切换BaseUrl
val baseUrl = if (BuildConfig.DEBUG) {
"https://api-dev.example.com/"
} else {
"https://api.example.com/"
}
RxHttpPlugins.setBaseUrl(baseUrl)
2. 网络缓存策略配置
利用CacheInterceptor实现缓存策略:
// rxhttp/src/main/java/rxhttp/wrapper/intercept/CacheInterceptor.kt
val cacheInterceptor = CacheInterceptor()
.setCacheDirectory(File(context.cacheDir, "rxhttp_cache"))
.setCacheMaxSize(100 * 1024 * 1024) // 100MB
.setCacheTime(60 * 60 * 24) // 默认缓存时间1天
RxHttp.init(getOkHttpClient())
.addInterceptor(cacheInterceptor)
3. 日志打印配置
配置详细日志,方便调试:
RxHttp.init(getOkHttpClient())
.setDebug(true)
.setLogger(object : ILogger {
override fun log(msg: String) {
Log.d("RxHttp", msg)
}
override fun log(json: String) {
Log.d("RxHttp-Json", JsonUtils.formatJson(json))
}
})
📚 总结与扩展阅读
通过本文介绍的拦截器、自定义参数和解析器,你已经掌握了RxHttp的高级用法,能够轻松实现:
- 全局请求参数添加
- 请求/响应数据加解密
- 统一异常处理
- 网络缓存策略
项目中还有更多高级特性等待探索:
- 断点续传功能:app/src/main/java/com/example/httpsender/vm/MultiTaskAwaitDownloader.kt
- 协程并发下载:app/src/main/java/com/example/httpsender/vm/MultiTaskFlowDownloader.kt
- 响应式编程支持:rxhttp/src/main/java/rxhttp/wrapper/coroutines/CallFlow.kt
RxHttp的设计理念是"让网络请求更简单",通过灵活的扩展机制,几乎可以满足所有网络请求场景需求。无论是简单的GET请求还是复杂的文件上传下载,RxHttp都能提供简洁优雅的API,帮助开发者专注于业务逻辑实现。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






