Retrofit无法创建类转换器问题排查求助
Retrofit调用TvShowService.getDetails时出现“Unable to create converter for class”错误排查
调用以下TvShowService接口的getDetails方法时,出现**"Unable to create converter for class"**错误:
interface TvShowService { @GET("tv/{tv_id}") suspend fun getDetails( @Path("tv_id") id: Int, @QueryMap queries: Map<String, String> ): TvShowDetailsDTO }
许多同类问题的解决方案建议检查待映射类是否存在重复属性,但TvShowDetailsDTO及其父类TvShowDTO并无重复属性,代码如下:
class TvShowDetailsDTO( backdropPath: String, @SerializedName("created_by") val createdBy: List<CreatedByDTO>, @SerializedName("episode_run_time") private val episodeRunTime: List<Int>, @SerializedName("first_air_date") val firstAirDate: String, genres: List<GenreDTO>, val homepage: String, id: Int, @SerializedName("in_production") val inProduction: Boolean, val languages: List<String>, @SerializedName("last_air_date") val lastAirDate: String, @SerializedName("last_episode_to_air") val lastEpisodeToAir: EpisodeDTO, name: String, val networks: List<NetworkDTO>, @SerializedName("next_episode_to_air") val nextEpisodeToAir: EpisodeDTO?, @SerializedName("number_of_episodes") val numberOfEpisodes: Int, @SerializedName("number_of_seasons") val numberOfSeasons: Int, originCountry: List<String>, originalLanguage: String, originalName: String, overview: String, popularity: Double, posterPath: String, @SerializedName("production_companies") val productionCompanies: List<ProductionCompanyDTO>, @SerializedName("production_countries") val productionCountries: List<ProductionCountryDTO>, val seasons: List<SeasonDTO>, @SerializedName("spoken_languages") val spokenLanguages: List<SpokenLanguageDTO>, val status: String, val tagline: String, val type: String, voteAverage: Double, voteCount: Int ) : TvShowDTO( backdropPath, firstAirDate, genres, id, name, originCountry, originalLanguage, originalName, overview, popularity, posterPath, voteAverage, voteCount ) { private fun formatTimeMeasurement(timeMeasurement: Int): String { val hours = timeMeasurement / 60 val minutes = timeMeasurement % 60 return String.format("%02d h %02d min", hours, minutes) } val formattedEpisodesRuntime: List<String> get() { return episodeRunTime.map { formatTimeMeasurement(it) } } } open class TvShowDTO( @SerializedName("backdrop_path") val backdropPath: String?, @SerializedName("first_air_date") private val firstAirDate: String, @SerialName("genre_ids") val genres: List<GenreDTO>, val id: Int, val name: String, @SerializedName("origin_country") val originCountry: List<String>, @SerializedName("original_language") val originalLanguage: String, @SerializedName("original_name") val originalName: String, val overview: String, val popularity: Double, @SerializedName("poster_path") val posterPath: String?, @SerializedName("vote_average") val voteAverage: Double, @SerializedName("vote_count") val voteCount: Int ) { private fun formatDate(date: String): String { val inputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) val outputFormat = SimpleDateFormat.getDateInstance() val formattedDate = inputFormat.parse(date) return outputFormat.format(formattedDate) } val formattedFirstAirDate: String get() { return if (firstAirDate.isNotEmpty()) { formatDate(firstAirDate) } else { "" } } }
NetworkModule中的Retrofit配置如下:
@Singleton @Provides fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build()
已确认依赖为最新版本,且功能逻辑相同的电影接口可正常填充MovieDetailsDTO。
可能原因及解决方案
- 注解不兼容:TvShowDTO中
genres字段使用了@SerialName,而Gson仅识别@SerializedName注解,将@SerialName("genre_ids")替换为@SerializedName("genre_ids")即可。 - 非空性不匹配:TvShowDetailsDTO构造函数中的
backdropPath、posterPath定义为非空String,但父类TvShowDTO中这两个字段是可空String?,接口返回的JSON中这两个字段可能为null,导致Gson无法构造对象。将TvShowDetailsDTO构造函数中的backdropPath: String和posterPath: String改为String?。 - 嵌套DTO类问题:检查
CreatedByDTO、EpisodeDTO等嵌套类是否存在注解错误、非空性不匹配,或缺少无参构造函数。如果使用Kotlin数据类,可添加kotlin-kapt插件并使用@NoArg注解生成无参构造,确保Gson能正常反射实例化。 - Gson Kotlin特性支持不足:默认Gson对Kotlin特性支持有限,可添加
com.google.gson:gson-kotlin依赖,并自定义Gson实例:
然后在Retrofit配置中使用该实例:val gson = GsonBuilder() .registerTypeAdapterFactory(KotlinAdapterFactory()) .create()GsonConverterFactory.create(gson)
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

