【问题标题】:Moshi Retrofit error: "Expected a string but was BEGIN_OBJECT"Moshi 改造错误:“应为字符串,但为 BEGIN_OBJECT”
【发布时间】:2016-08-28 21:27:46
【问题描述】:

我这样构建了我的 Retrofit 实例:

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(server.url("/"))
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build();

然后我像这样调用我的 MockWebServer 实例:

server.enqueue(new MockResponse().setBody(jsonStr));

jsonStr 是这样构建的:

MyModel model = new MyModel("HOME", "AWAY", "ENTERTAIN", "NIGHT", "MUTE",
            "VOLUME", "SCENE 1", "SCENE 2", "SCENE 3");
JsonAdapter<MyModel> jsonAdapter = moshi.adapter(MyModel.class).toJson(model);

但是,此时代码崩溃了:

Response response = api.getString().execute();

例外是:

com.squareup.moshi.JsonDataException: 应为字符串,但路径 $ 处为 BEGIN_OBJECT

我做错了什么?

【问题讨论】:

    标签: android retrofit2 mockwebserver moshi


    【解决方案1】:

    我找到了解决方案: 我的api接口需要有

    @GET("/") Call<JsonObject> getString();
    

    不是

    @GET("/") Call<String> getString();
    

    原因是我在模拟 JSON 响应,而不是纯字符串。

    【讨论】:

      【解决方案2】:

      就我而言,当我的代码如下时,我得到了问题中提到的相同错误。

      com.squareup.moshi.JsonDataException: Expected BEGIN_OBJECT but was STRING at path $.elections[0].ocdDivisionId
      
      private val moshi = Moshi.Builder()
          .add(KotlinJsonAdapterFactory())
          .add(DateAdapter())
          .add(ElectionAdapter())
          .build()
      

      问题与 ElectionAdapter 有关。

      改变添加适配器的顺序后,将 .add(ElectionAdapter()) 放在最上面,如下图,问题解决了:

      private val moshi = Moshi.Builder()
          .add(ElectionAdapter())
          .add(KotlinJsonAdapterFactory())
          .add(DateAdapter())
          .build()
      

      【讨论】:

      • 什么是ElectionAdapter
      • @IgorGanapolsky 这与我们在 Udacity 在线课程中进行的项目中的自定义适配器有关。
      • 是的,它是一个自定义适配器 :)
      • 也来自 Udacity,这很有帮助。但你能解释一下原因吗?
      【解决方案3】:

      就我而言,我省略了 ScalarsConverterFactory 来解析 JSONString

      你看我的 API 调用应该返回一个 JSON 字符串

      ` @GET("neo/rest/v1/feed")
           suspend fun getNearEarthObjects(@Query("api_key") apiKey: String): String`
      

      在构建 Retrofit 对象时,我使用 Moshi 来解析 Kotlin 对象,但我忘记了 ScalarsConverter

      //Build Retrofit Object
      val retrofit =
          Retrofit.Builder()
              .addConverterFactory(ScalarsConverterFactory.create())
              .addConverterFactory(MoshiConverterFactory.create(moshi))
              .baseUrl(BASE_URL)
              .build()
      

      【讨论】:

      • 足够的部分是ScalarsConverterFactory应该在MoshiConverterFactory之前。
      • 谢谢@AlexanderSkvortsov 这对我有用
      猜你喜欢
      • 1970-01-01
      • 2015-06-09
      • 1970-01-01
      • 2014-12-03
      • 2018-04-21
      • 1970-01-01
      • 2020-05-19
      • 2017-01-19
      • 2017-05-16
      相关资源
      最近更新 更多