Retrofit2+GsonでJsonのint型で返却される真偽値をPOJOでboolean型に置き換える
発端
SerializedNameアノテーションを書いてもFieldNamePolicyを設定してもオブジェクトが正しく変換されなかった。
Jacksonに変えてもうまくいかない…。
と思ったらintで返却されている真偽値を、javaのPOJOでbooleanを指定していた。
フィールドをintにしたら動いたが、気持ち悪いのでGsonでよしなにしてもらう。
gradle
... // network library compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'com.squareup.okhttp3:logging-interceptor:3.9.0' // Rx compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.1.3' // gson compile 'com.google.code.gson:gson:2.8.2' ...
Retrofit
public class ApiClient { static private Context mContext; static private Retrofit retrofit; public static void init(Context context){ mContext = context; OkHttpClient httpClient = new OkHttpClient.Builder() .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE)) .addInterceptor(new AppCustomInterceptor()) .addInterceptor(new AddCookiesInterceptor()) .addInterceptor(new ReceivedCookiesInterceptor()) .readTimeout(30, SECONDS) .writeTimeout(30, SECONDS) .connectTimeout(30, SECONDS) .build(); Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(boolean.class, new BooleanTypeAdapter()) .create(); retrofit = new Retrofit.Builder() .client(httpClient) .baseUrl(BuildConfig.API_ENDPOINT) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } public static <V> V getApi(Class<V> clazz){ return retrofit.create(clazz); } }
BooleanTypeAdapter
public class BooleanTypeAdapter implements JsonDeserializer<Boolean> { public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { int code = json.getAsInt(); return code == 0; } }
を追加してGsonにregisterするだけ。
これでPOJO側でbooleanを指定していても勝手にintから変換してくれる。