天天看點

Retrofit 自定義Converter實作發送String和接收JSON

Retrofit已經為使用者提供了六種Converter,如下:

  • Gson: 

    com.squareup.retrofit2:converter-gson

  • Jackson: 

    com.squareup.retrofit2:converter-jackson

  • Moshi: 

    com.squareup.retrofit2:converter-moshi

  • Protobuf: 

    com.squareup.retrofit2:converter-protobuf

  • Wire: 

    com.squareup.retrofit2:converter-wire

  • Simple XML: 

    com.squareup.retrofit2:converter-simplexml

  • Scalars (primitives, boxed, and String): 

    com.squareup.retrofit2:converter-scalars

但最近項目要求,發送時String,接收JSON,目前的Converter設定後,都是同時針對發送和接收,是以我們需要自定義Converter。不過如上的Converter已經有String和JSON的處理方式,我們可以組合 

com.squareup.retrofit2:converter-gson和com.squareup.retrofit2:converter-scalars,進而實作項目要求。

請求的字元串轉換:

public class StringRequestBodyConverter<T> implements Converter<T, RequestBody> {

    private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain; charset=UTF-8");

    StringRequestBodyConverter() {
    }

    @Override
    public RequestBody convert(T value) throws IOException {
        return RequestBody.create(MEDIA_TYPE, String.valueOf(value));
    }



}
           

響應的JSON轉換:

public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {

    private final Gson gson;
    private final TypeAdapter<T> adapter;

    JsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }

    @Override
    public T convert(ResponseBody value) throws IOException {
        JsonReader jsonReader = gson.newJsonReader(value.charStream());
        try {
            return adapter.read(jsonReader);
        } finally {
            value.close();
        }
    }


}
           

Converter的實作工廠:

public class ExtConverterFactory extends Converter.Factory{

    private final Gson gson;


    public static ExtConverterFactory create() {
        return new ExtConverterFactory(new Gson());
    }

    private ExtConverterFactory(Gson gson) {
        this.gson = gson;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new JsonResponseBodyConverter<>(gson, adapter);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (type == String.class
                || type == boolean.class
                || type == Boolean.class
                || type == byte.class
                || type == Byte.class
                || type == char.class
                || type == Character.class
                || type == double.class
                || type == Double.class
                || type == float.class
                || type == Float.class
                || type == int.class
                || type == Integer.class
                || type == long.class
                || type == Long.class
                || type == short.class
                || type == Short.class) {
            return new StringRequestBodyConverter();
        }
        return null;

    }

}
           

之後就能初始化Retrofit如下,進而實作發送String,接收JSON

Retrofit  retrofit = new Retrofit.Builder()
                .addConverterFactory(ExtConverterFactory.create())
                .client(new OkHttpClient())
                .baseUrl("http://api.test.com/")
                .build();


  NetApi netApi = retrofit.create(NetApi.class);
           

參考文檔:https://square.github.io/retrofit/