【发布时间】:2021-04-01 07:22:22
【问题描述】:
我在我的应用程序中使用 Retrofit (v2.9.0) 和 Moshi (v1.11.0)。我尝试以这种方式调用端点:
@FormUrlEncoded
@PATCH("anime/{anime_id}/my_list_status")
fun updateListStatus(
@Path("anime_id") animeId: Long,
@Field("num_watched_episodes") nbWatchedEpisodes: Int,
@Field("score") score: Double,
@Field("status") watchStatus: WatchStatus,
): Single<MyListStatus>
但是 WatchStatus->Json 转换没有按预期工作。 WatchStatus 是一个简单的枚举类:
enum class WatchStatus {
COMPLETED,
DROPPED,
ON_HOLD,
PLAN_TO_WATCH,
WATCHING,
}
我创建了一个自定义适配器,因为我的应用使用大写枚举名称,而后端使用小写名称:
class AnimeMoshiAdapters {
/* Others adapters */
@ToJson
fun watchStatusToJson(watchStatus: WatchStatus): String =
watchStatus.toString().toLowerCase(Locale.getDefault())
@FromJson
fun watchStatusFromJson(watchStatus: String): WatchStatus =
WatchStatus.valueOf(watchStatus.toUpperCase(Locale.getDefault()))
}
我以这种方式创建我的 Moshi 实例:
Moshi.Builder()
.addLast(KotlinJsonAdapterFactory())
.add(AnimeMoshiAdapters())
.build()
我的 Retrofit 实例使用它(通过 Koin 注入):
Retrofit.Builder()
.baseUrl(get<String>(named("baseUrl")))
.client(get(named("default")))
.addConverterFactory(MoshiConverterFactory.create(get()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
在解析 Json 以创建 WatchStatus 枚举时,将使用适配器。这是值得注意的,因为如果我删除我的自定义适配器,调用将失败并出现错误“com.squareup.moshi.JsonDataException: Expected one of [COMPLETED, DROPPED, ON_HOLD, PLAN_TO_WATCH, WATCHING]”。 当我尝试调用上面指定的端点时,Json 中的 WatchStatus 的转换是错误的,并且枚举名称保持大写,这意味着我的自定义适配器未使用。如果我检查改造日志,我可以看到它发送“num_watched_episodes=12&score=6.0&status=ON_HOLD”,因此状态不会转换为小写。
如果我尝试使用相同的 Moshi 实例手动转换 Json 中的 WatchStatus,它会按预期工作,所以我相信我的自定义适配器实现是正确的。
如何让 Retrofit 在此调用中使用我的自定义 Moshi 适配器?
【问题讨论】:
标签: android json enums retrofit moshi