Retrofit custom Converter implements sending String and receiving JSON

Keywords: Retrofit JSON xml github

Retrofit has provided users with six converters, as follows:

  • Gsoncom.squareup.retrofit2:converter-gson
  • Jacksoncom.squareup.retrofit2:converter-jackson
  • Moshicom.squareup.retrofit2:converter-moshi
  • Protobufcom.squareup.retrofit2:converter-protobuf
  • Wirecom.squareup.retrofit2:converter-wire
  • Simple XMLcom.squareup.retrofit2:converter-simplexml
  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

However, the latest project requires that String and JSON should be sent and received at the same time. After the current Converter is set, we need to customize the Converter. However, the above Converter already has String and JSON processing methods. We can combine com.squareup.retrofit2: Converter gson and com.squareup.retrofit2: Converter scalars to achieve the project requirements.

 

Requested string conversion:

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 conversion of response:

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


}

The implementation factory of 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;

    }

}

After that, you can initialize Retrofit as follows to send String and receive JSON.

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


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

 

 

 

 

Reference documents: https://square.github.io/retrofit/

Posted by Spear Chucka on Sat, 26 Oct 2019 12:05:05 -0700