web-dev-qa-db-ja.com

改造によるhttpリクエスト本文のエンコードを防止する

以下の形式の文字列をhttppostリクエストの本文として渡そうとしています。

param1=PARAM1&param2=PARAM2&param3=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);
}
12
user672009

質問に直接答えるには、メソッドパラメータタイプとして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);
7
Jake Wharton

リクエスト本文にシリアル化されたクラス(HashMapなど)があり、それをエンコードしないようにしたい場合(vezikonや私の問題のように)、次を使用してエスケープを無効にしたカスタムGsonを作成できます。

Gson gson = new GsonBuilder().disableHtmlEscaping().create();

このコンバーターを残りのアダプターに渡します。

yourRestAdapter  = new RestAdapter.Builder()
    .setEndpoint(.....)
    .setClient(.....)
    .setConverter(new GsonConverter(gson))
    .build();

このようにして、投稿本文の「=」文字は送信中にそのまま残ります。

9
Murat Ögat

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'
0
hnilsen