json 我的改型gson反序列化器看不到枚举

ioekq8ef  于 2023-03-13  发布在  其他
关注(0)|答案(1)|浏览(123)

每当我从JSON看起来像{"rights":[{"name":"stock_management","right":true}]}的服务器得到响应时,我的改进使用类SimpleResponse<T>将其转换为我想要的响应,但相反,我得到的是作为权限值的空列表。

data class SimpleResponse<T>(
    val data: T? = null,
    val error: String? = null,
    val rights: List<LMSPermission> = emptyList()
)

@Entity
data class LMSPermission(
    @PrimaryKey(autoGenerate = false)
    val name: Permission,
    val right: Boolean = false
) {
    enum class Permission(val lmsName: String) {
        @SerializedName("stock_management")
        STOCK_PERMISSION("stock_management")
    }
}

我试着创建gson示例并从中生成类,但是一切都很好,所以我试着在我的改型示例中添加拦截器,然后我试着从response中获取类示例,结果成功了。

@Provides
    @Singleton
    fun provideRetrofitDAO(): RetrofitDao {
        val gson = GsonBuilder()
            .registerTypeAdapter(Event::class.java, EventDeserializer())

        val logging = HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY)
        val httpClient = OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .addInterceptor(logging)
            .addInterceptor { chain ->
                val response = chain.proceed(chain.request().newBuilder().build())
                Log.d(TAG, "provideRetrofitDAO: $response")
                response.let {
                    if (it.code == 200)
                        Log.d(TAG, "provideRetrofitDAO: ${gson.create().fromJson<SimpleResponse<Any>>(it.body.string(), TypeToken.getParameterized(SimpleResponse::class.java, Any::class.java).type)}")
                }
                response
            }
        val retrofitBuilder =
            Retrofit
                .Builder()
                .baseUrl(if (MainActivity.debug) API_BASE_URL_DEBUG else API_BASE_URL)
                .addConverterFactory(
                    GsonConverterFactory.create(gson.create())
                )
                .callbackExecutor(Executors.newSingleThreadExecutor())
        val retrofit =
            retrofitBuilder
                .client(
                    httpClient.build()
                )
                .build()

        return retrofit.create(RetrofitDao::class.java)
    }

在这一点上,我很肯定,转换器工厂是在故障,但我不知道如何修复,也不知道如何检查,如果它真的是一个问题。

vyswwuz2

vyswwuz21#

看起来我写了自己的GsonConverterFactory,在那里我使用fromJson方法而不是getAdapter的适配器是答案。不要问我为什么这样做,但这里是代码,MyTypeAdapter没有真正实现,因为我把它用作Type变量的容器。

class MyGsonConverterFactory(val gson: Gson) : Converter.Factory() {
        override fun responseBodyConverter(
            type: Type,
            annotations: Array<out Annotation>,
            retrofit: Retrofit
        ): Converter<ResponseBody, *> {
            val adapter = MyTypeAdapter<Any>(type)
            return GsonResponseBodyConverter(gson, adapter)
        }

        override fun requestBodyConverter(
            type: Type,
            parameterAnnotations: Array<Annotation?>,
            methodAnnotations: Array<Annotation?>,
            retrofit: Retrofit
        ): Converter<*, RequestBody> {
            val adapter = gson.getAdapter(TypeToken.get(type))
            return GsonRequestBodyConverter(gson, adapter)
        }
    }

    internal class GsonResponseBodyConverter<T>(
        private val gson: Gson,
        private val adapter: TypeAdapter<T>
    ) :
        Converter<ResponseBody, T> {
        @Throws(IOException::class)
        override fun convert(value: ResponseBody): T {
            (adapter as? MyTypeAdapter)?.typeToken!!.let {
                val test = gson.fromJson<T>(value.string(), it)
                Log.d(TAG, "convert: $test")
                return test
            }
        }
    }

    internal class GsonRequestBodyConverter<T>(
        private val gson: Gson,
        private val adapter: TypeAdapter<T>
    ) : Converter<T, RequestBody> {
        @Throws(IOException::class)
        override fun convert(value: T): RequestBody {
            val buffer = Buffer()
            val writer: Writer = OutputStreamWriter(buffer.outputStream(), UTF_8)
            val jsonWriter = gson.newJsonWriter(writer)
            adapter.write(jsonWriter, value)
            jsonWriter.close()
            return buffer.readByteString().toRequestBody(MEDIA_TYPE)
        }

        companion object {
            private val MEDIA_TYPE: MediaType = "application/json; charset=UTF-8".toMediaType()
            private val UTF_8 = Charset.forName("UTF-8")
        }
    }

    internal class MyTypeAdapter<T>(val typeToken: Type) : TypeAdapter<T>() {
        override fun write(out: JsonWriter?, value: T) {}
        override fun read(`in`: JsonReader?): T { TODO() }
    }

相关问题