Retrofit2.0ノート——addConverterFactoryはxmlとjson形式の応答データを同時にサポートする
6535 ワード
Retrofit 2の特徴的な機能は、
注意:
しかし、実測の結果、このコンバータはRetrofitに設定された後、正常に動作しない.
デフォルトでは、Gson(JSON)とSimpleXML(XML)変換器の動作のため、1つのRetrofitインスタンスでは両方の変換器を同時にサポートできません.このように書くと、
では,xmlフォーマットを変換した戻りデータは正常であり,jsonフォーマットを変換した戻りデータはクラッシュする.このように書くと、
では、jsonフォーマットを変換する戻りデータは正常であり、xmlフォーマットを変換する戻りデータはクラッシュする.つまり、先に追加したものだけが正常に使えます.
では、jsonとxmlフォーマットを同時に正常に変換できる案はありますか?あるに違いない!
解決策
Retrofitが呼び出すインタフェースメソッドに注釈を追加し、リクエストの応答データフォーマットを説明します.次にConverterFactoryをカスタマイズし、注記のプロパティ値に基づいてjsonコンバータを使用するかxmlコンバータを使用するかを決定します.
インプリメンテーションコード
カスタムConverterFactory(
テストコード
まとめ
この問題には解決策があるが、需要シーンは少ないはずだ.一般的なバックグラウンドサービスは、同じbaseUrlベースのapiインタフェースであり、一般的には統合応答データフォーマットである.appで異なるバックグラウンドサービスurlからデータを要求する必要がある場合にのみ、Retrofit自体がマルチbaseUrlをサポートする複数のフォーマットの戻りデータが発生する可能性があります.
addConverterFactory()
の方法でデータ変換器を設定することで、httpリクエストの応答データをJavaBeanに変換することができます.バックグラウンドで一般的な2つの戻りデータフォーマット:jsonとxmlのように、それぞれGsonConverterFactory
とSimpleXmlConverterFactory
で変換できます.対応するgradle依存度は、次のとおりです.implementation 'com.squareup.retrofit2:converter-gson:2.x.x'
implementation 'com.squareup.retrofit2:converter-simplexml:2.x.x'
注意:
SimpleXmlConverterFactory
は現在Deprecatedとして宣言されており、推奨される代替案はJAXB converter(JaxbConverterFactory
)であり、対応するgradle依存は以下の通りである.implementation 'com.squareup.retrofit2:converter-jaxb:2.x.x'
しかし、実測の結果、このコンバータはRetrofitに設定された後、正常に動作しない.
デフォルトでは、Gson(JSON)とSimpleXML(XML)変換器の動作のため、1つのRetrofitインスタンスでは両方の変換器を同時にサポートできません.このように書くと、
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(SimpleXmlConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
では,xmlフォーマットを変換した戻りデータは正常であり,jsonフォーマットを変換した戻りデータはクラッシュする.このように書くと、
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(SimpleXmlConverterFactory.create()
.build();
では、jsonフォーマットを変換する戻りデータは正常であり、xmlフォーマットを変換する戻りデータはクラッシュする.つまり、先に追加したものだけが正常に使えます.
では、jsonとxmlフォーマットを同時に正常に変換できる案はありますか?あるに違いない!
解決策
Retrofitが呼び出すインタフェースメソッドに注釈を追加し、リクエストの応答データフォーマットを説明します.次にConverterFactoryをカスタマイズし、注記のプロパティ値に基づいてjsonコンバータを使用するかxmlコンバータを使用するかを決定します.
インプリメンテーションコード
ResponseFormat
などのカスタム注釈:/**
* , :{@link #JSON} {@link #XML}
*/
@Target(METHOD)
@Retention(RUNTIME)
public @interface ResponseFormat {
String JSON = "json";
String XML = "xml";
String value() default "";
}
カスタムConverterFactory(
JsonOrXmlConverterFactory
など)public class JsonOrXmlConverterFactory extends Converter.Factory {
private final Converter.Factory xmlFactory = SimpleXmlConverterFactory.create();
private final Converter.Factory jsonFactory = GsonConverterFactory.create();
public static JsonOrXmlConverterFactory create() {
return new JsonOrXmlConverterFactory();
}
@Nullable
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
for (Annotation annotation : annotations) {
if (!(annotation instanceof ResponseFormat)) {
continue;
}
String value = ((ResponseFormat) annotation).value();
if (ResponseFormat.JSON.equals(value)) {
return jsonFactory.responseBodyConverter(type, annotations, retrofit);
} else if (ResponseFormat.XML.equals(value)) {
return xmlFactory.responseBodyConverter(type, annotations, retrofit);
}
}
return null;
}
}
テストコード
interface TestApi {
@GET("testapi/getjson.php/")
@ResponseFormat("json")
Observable getJson();
@GET("testapi/getxml.php/")
@ResponseFormat("xml")
Observable getXml();
}
//……
Retrofit mRetrofit = new Retrofit.Builder()
.baseUrl(URL)
.addConverterFactory(JsonOrXmlConverterFactory.create()
.build();
//……
public void getCode(Consumer consumer) {
TestApi testApi = mRetrofit.create(TestApi.class);
testApi.getJson()
.subscribe(consumer);
}
public void getXml(Consumer consumer) {
TestApi testApi = mRetrofit.create(TestApi.class);
testApi.getXml()
.subscribe(consumer);
}
まとめ
この問題には解決策があるが、需要シーンは少ないはずだ.一般的なバックグラウンドサービスは、同じbaseUrlベースのapiインタフェースであり、一般的には統合応答データフォーマットである.appで異なるバックグラウンドサービスurlからデータを要求する必要がある場合にのみ、Retrofit自体がマルチbaseUrlをサポートする複数のフォーマットの戻りデータが発生する可能性があります.