以下の形式の文字列をhttppostリクエストの本文として渡そうとしています。
param1=PARAM1¶m2=PARAM2¶m3=PARAM3
しかし、retrofitは私の体をエンコードして、=が\ u003dになり、&が\ u0026になるようにします。そして、私は実際には次のような文字列になります。
param1\u003dPARAM1\u0026param2\u003dPARAM2\u0026param3\u003dPARAM3
どうすればそれを防ぐことができますか?
私の改造レストAPIは次のように定義されています。
public interface RestAPI {
@POST("/oauth/token")
public void getAccessToken(@Body String requestBody, Callback<Response> response);
}
質問に直接答えるには、メソッドパラメータタイプとしてTypedString
を使用できます。値が変更される理由は、RetrofitがJSONとしてエンコードするためにString
をGsonに渡しているためです。 TypedString
または任意のTypedOutput
サブクラスを使用すると、この動作を防ぐことができます。基本的に、直接リクエストの本文の作成を自分で処理するようにRetrofitに指示します。
ただし、そのペイロードの形式はフォームURLエンコードと呼ばれます。 Retrofitはそれをネイティブでサポートしています。メソッド宣言は実際には次のようになります。
@FormUrlEncoded
@POST("/oauth/token")
void getAccessToken(
@Field("param1") String param1,
@Field("param2") String param2,
@Field("param3") String param3,
Callback<Response> callback);
リクエスト本文にシリアル化されたクラス(HashMapなど)があり、それをエンコードしないようにしたい場合(vezikonや私の問題のように)、次を使用してエスケープを無効にしたカスタムGsonを作成できます。
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
このコンバーターを残りのアダプターに渡します。
yourRestAdapter = new RestAdapter.Builder()
.setEndpoint(.....)
.setClient(.....)
.setConverter(new GsonConverter(gson))
.build();
このようにして、投稿本文の「=」文字は送信中にそのまま残ります。
Kotlinを使用
Retrofit 2の場合、Gsonコンバータファクトリを使用してRetrofitを初期化できます。
val builder = GsonBuilder().disableHtmlEscaping().create()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(builder))
.client(monoOkHttpClient())
.build()
このビルダーは、json出力からエスケープを削除する必要があります。
Gradleファイルの依存関係:
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'