Retrofit同时注册Gson和Jackson转换器工厂的适配问题
解决方案
你的实现思路是完全正确的,Retrofit的ConverterFactory机制本身就支持返回null来跳过当前工厂,交给后续注册的其他工厂处理,你只需要在自定义的JacksonConverterFactory中增加「当前类型是否已注册自定义Jackson反序列化器」的判断逻辑即可。
核心判断逻辑
Jackson对所有内置的标准反序列化器都标记了@JacksonStdImpl注解,你可以通过ObjectMapper获取指定类型的实际生效反序列化器,判断是否存在该注解即可识别是不是自定义注册的反序列化器。
完整实现代码
1. 自定义Jackson转换器工厂
import com.fasterxml.jackson.databind.JacksonStdImpl import com.fasterxml.jackson.databind.ObjectMapper import okhttp3.ResponseBody import retrofit2.Converter import retrofit2.Retrofit import java.lang.reflect.Type class CustomJacksonConverterFactory private constructor( private val mapper: ObjectMapper ) : Converter.Factory() { companion object { fun create(mapper: ObjectMapper): CustomJacksonConverterFactory { return CustomJacksonConverterFactory(mapper) } } override fun responseBodyConverter( type: Type, annotations: Array<out Annotation>, retrofit: Retrofit ): Converter<ResponseBody, *>? { val javaType = mapper.typeFactory.constructType(type) return try { // 获取该类型实际生效的反序列化器 val deserializer = mapper.deserializationContext.findRootValueDeserializer(javaType) // 无@JacksonStdImpl注解则为自定义反序列化器 val hasCustomDeserializer = deserializer.javaClass.getAnnotation(JacksonStdImpl::class.java) == null if (hasCustomDeserializer) { val reader = mapper.readerFor(javaType) JacksonResponseBodyConverter(reader) } else { // 返回null,交给下一个转换器工厂处理 null } } catch (e: Exception) { // Jackson解析异常直接跳过,走后续Gson逻辑 null } } private class JacksonResponseBodyConverter<T>( private val reader: ObjectReader ) : Converter<ResponseBody, T> { override fun convert(value: ResponseBody): T? { return value.use { reader.readValue(it.charStream()) } } } // 如有请求体序列化需求,可按需重写requestBodyConverter方法,逻辑和上述类似 }
2. Retrofit初始化配置
注意转换器工厂的注册顺序,必须把自定义Jackson工厂放在Gson工厂前面:
// 初始化配置了自定义反序列化器的ObjectMapper val module = SimpleModule() module.addDeserializer(User::class.java, UserDeserializer()) val objectMapper = ObjectMapper() objectMapper.registerModule(module) val retrofit = Retrofit.Builder() .baseUrl("你的接口根地址") .addConverterFactory(CustomJacksonConverterFactory.create(objectMapper)) // Jackson处理不了的请求会自动交给Gson处理 .addConverterFactory(GsonConverterFactory.create()) .build()
注意事项
- 该逻辑同时适配普通类型、泛型类型(如
List<User>)以及通过@JsonDeserialize注解标注的自定义反序列化场景。 - 如有特殊类型需要强制走Jackson或Gson,可在判断逻辑中新增白名单/黑名单规则灵活调整。
内容的提问来源于stack exchange,提问作者lostintranslation
相关产品推荐
相关产品推荐

