C-FRONT

エモくありたい

RetrofitでJson以外のresponseでのMalformedJsonExceptionに対応する

APIJsonではなく例えばStringなどJsonではない値を返す場合、retrofitのconverterにGSONしか追加していないと以下のエラーが発生する。

com.google.gson.stream.MalformedJsonException: Expected value at line 1 column 6 path 

そんな時はRetrofitにconverterを指定できる。今回の場合のようなprimitiveな値を扱う場合はScalars Converterが使える。

implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version"
return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .client(okHttpClient)
                .build()

retrofitのインスタンスを作る時にaddConverterFactoryを追加するとJsonでもStringでも同じようにAPIからのレスポンスを受け取れる。

ref: https://stackoverflow.com/questions/36523972/how-to-get-string-response-from-retrofit2

converterは複数設定できるので、APIからのレスポンスにJsonのものとStringのものが混じっていれば両方追加しておけばよい。

If the first converter accepts the challenge, the rest of the list will not be asked.

ref: https://futurestud.io/tutorials/retrofit-2-introduction-to-multiple-converters

ただ上の記事にもあるように追加するconverterの順番によって挙動は変わるようで、

.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))

この順番であれば問題ないが、順番を反対にすると変わらずMalformedJsonExceptionが発生する。