首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用中断的远程API解析json

用中断的远程API解析json
EN

Stack Overflow用户
提问于 2017-12-02 15:42:22
回答 1查看 437关注 0票数 2

这是我的模型课

data class Article( val id: Int? = 0, val is_local: Boolean? = false, val comments: List<Comment?>? = listOf())

这是杰森

代码语言:javascript
运行
复制
  {
    "id": 33,
    "is_local": "true",
    "comments":
         [
          { "url": "aaa" },

          { "url": "bbb" },

          { "url": "ccc" )

     ]

}

我使用这个自定义适配器在解析错误的情况下返回默认值,就像我的例子是is_local字段一样。

代码语言:javascript
运行
复制
class DefaultOnDataMismatchAdapter<T> private constructor(private val delegate: 
   JsonAdapter<T>, private val defaultValue: T?) : JsonAdapter<T>() {

 @Throws(IOException::class)
  override fun fromJson(reader: JsonReader): T? =
        try {
            delegate.fromJsonValue(reader.readJsonValue())
        } catch (e: Exception) {
            println("Wrongful content - could not parse delegate " + 
delegate.toString())
            defaultValue
        }

@Throws(IOException::class)
override fun toJson(writer: JsonWriter, value: T?) {
    delegate.toJson(writer, value)
}

  companion object {
    @JvmStatic
    fun <T> newFactory(type: Class<T>, defaultValue: T?): 
    JsonAdapter.Factory {
        return object : JsonAdapter.Factory {
            override fun create(requestedType: Type, annotations: 
      Set<Annotation>, moshi: Moshi): JsonAdapter<*>? {
                if (type != requestedType) {
                    return null
                }
                val delegate = moshi.nextAdapter<T>(this, type, 
          annotations)
                return DefaultOnDataMismatchAdapter(delegate, 
     defaultValue)
             }

         }
      }
   }

}

并且我的测试失败和布尔值不是false,我已经将上面的适配器添加到moshi中。

代码语言:javascript
运行
复制
@Before
fun createService() {

    val moshi = Moshi.Builder()


    .add(DefaultOnDataMismatchAdapter
                           .newFactory(Boolean::class.java,false))
            .add(KotlinJsonAdapterFactory())
            .build()

    val retrofit = Retrofit.Builder()
            .baseUrl(mockWebServer.url("/"))
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()

    service =  retrofit.create(ApiStores::class.java)



}




@Test
fun getBooleanParsingError() {

    enqueueResponse(case1)

    val article = service.getArticle().execute()

    assert(article.body()!!).isNotNull()
    assert(article.body()!!.is_local).isEqualTo(false)  // test fail here 

}

但是,当我将模型类中的is_local字段的数据类型更改为不可空时,它可以工作。

EN

回答 1

Stack Overflow用户

发布于 2017-12-02 21:12:14

问题是kotlin.Booleankotlin.Boolean?类型对应于两种不同的Java类型:

  • kotlin.Booleanboolean Java原语类型
  • kotlin.Boolean?java.lang.Boolean Java类型

在您的测试中,您为kotlin.Boolean (即boolean类型)创建了一个适配器,而在您的数据模型中,您有一个kotlin.Boolean? (即java.lang.Boolean类型)。因此,当调用Factory的方法Factory时,您处于type != requestedType的情况,因此没有创建适配器,而是使用KotlinJsonAdapter。此时,由于Json的is_local字段是而不是--一个布尔值(而是一个字符串),所以应该会引发异常。

如果您将数据模型或适配器更改为使用相同的类型,则您所处的情况是type == requestedType,因此您的适配器将被创建,异常将一如既往地抛出,但您添加了一个返回默认值的catch块。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47609562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档