Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moshi Retrofit error: "Expected a string but was BEGIN_OBJECT"

I built my Retrofit instance like this:

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

Then I am calling my MockWebServer instance like this:

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

Where jsonStr is built like this:

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);

However, the code crashes at this point:

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

The exception is:

com.squareup.moshi.JsonDataException: Expected a string but was BEGIN_OBJECT at path $

What did I do wrong?

like image 698
IgorGanapolsky Avatar asked May 03 '16 17:05

IgorGanapolsky


3 Answers

I found the solution: My api interface needed to have

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

NOT

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

The reason is that I am mocking a JSON response, not a plain String.

like image 175
IgorGanapolsky Avatar answered Nov 04 '22 04:11

IgorGanapolsky


In my case, when my codes are as the following, i get the same error mentioned in the question.

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()

The problem is related to ElectionAdapter.

After changing the order of adding adapters, namely putting .add(ElectionAdapter()) at the top as show below, the problem is solved :

private val moshi = Moshi.Builder()
    .add(ElectionAdapter())
    .add(KotlinJsonAdapterFactory())
    .add(DateAdapter())
    .build()
like image 29
oiyio Avatar answered Nov 04 '22 03:11

oiyio


For my case I omitted the ScalarsConverterFactory for parsing the JSONString

You see my API Call was supposed to return a JSON String

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

When building the Retrofit Object I had the Moshi for parsing Kotlin Objects but I forgot the ScalarsConverter

//Build Retrofit Object
val retrofit =
    Retrofit.Builder()
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(MoshiConverterFactory.create(moshi))
        .baseUrl(BASE_URL)
        .build()
like image 34
Tonnie Avatar answered Nov 04 '22 05:11

Tonnie