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/