问题 防止改造编码我的http请求正文


我正在尝试传递下面格式的字符串作为http post请求的正文。

param1=PARAM1&param2=PARAM2&param3=PARAM3

但改装编码我的身体,以便=成为\ u003d和&成为\ u0026。我最终得到一个实际上看起来像这样的字符串:

param1\u003dPARAM1\u0026param2\u003dPARAM2\u0026param3\u003dPARAM3

我怎么能防止这种情况?

我的改造休息api定义如下。

public interface RestAPI {
    @POST("/oauth/token")
    public void getAccessToken(@Body String requestBody, Callback<Response> response);
}

1266
2017-10-29 17:49


起源



答案:


要直接回答这个问题,您可以使用 TypedString 作为方法参数类型。改变价值的原因是因为Retrofit正在处理 String 到Gson以编码为JSON。运用 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
2017-10-29 19:35



我正在尝试将body作为类,但其中的一些变量包含加密字符串,如“66PdGFKsvyyYaVTGJ / nAYQ ==”......任何想法如何防止=符号转换为\ u003d - mnagy


答案:


要直接回答这个问题,您可以使用 TypedString 作为方法参数类型。改变价值的原因是因为Retrofit正在处理 String 到Gson以编码为JSON。运用 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
2017-10-29 19:35



我正在尝试将body作为类,但其中的一些变量包含加密字符串,如“66PdGFKsvyyYaVTGJ / nAYQ ==”......任何想法如何防止=符号转换为\ u003d - mnagy


如果你在请求体中有一个序列化的类(比如HashMap),并且你想要阻止编码(比如vezikon和我的问题),你可以使用以下命令创建一个带有禁用转义的自定义Gson:

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

将此转换器传递给您的其他适配器:

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

这样,帖子正文中的“=”字符在提交时保持不变。


9
2018-03-27 01:02



inretrofit 2,我们不能这样使用它 - Choletski
好吧,这个答案来自Retrofit 1天,但是你不能像Retrofit 2一样使用它吗? (我还没有测试过):Gson gson = new GsonBuilder()。disableHtmlEscaping()。create(); Retrofit retrofit = new Retrofit.Builder()。baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create(gson))。client(okHttpClient).build(); - Murat Ögat
什么是RestAdapter?@MuratÖgat - Bipin Bharti
它不适用于Retrofit 2.请提出其他一些建议 - Rahul Gupta


可以通过以下解决方法修复此问题。

@POST("yourString")
Call<YourResponseModel> yourCallMethod(@Query("yourKey") String yourValue,
                                          @Query("yourKey") String yourValue,
                                          @Query("yourKey") String yourValue);

注意:在这种情况下,请勿使用“@FormUrlEncoded”。

参考这里 - https://github.com/square/retrofit/issues/1407


0
2018-05-13 18:34





使用Kotlin

对于Retrofit 2,您可以使用Gson转换器工厂初始化改造。

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
2018-01-29 12:54



这不适合我。我正在使用''com.squareup.retrofit2:retrofit:2.3.0''&&''com.squareup.retrofit2:converter-gson:2.3.0''。请帮帮我 - Rahul Gupta
@RahulGupta你也需要Scalars。 implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'  我已将deps添加到我的答案中。 - hnilsen
它不支持..请检查..'private static final RestAdapter REST_ADAPTER = new RestAdapter .Builder()。setConverter(new GsonConverter(gson))//避免在Request .setEndpoint(API_URL).setRequestInterceptor(requestInterceptor)中发送编码特殊字符).setLogLevel(RestAdapter.LogLevel.FULL).setClient(new Ok3Client(new OkHttpClient()))。build(); “ - Rahul Gupta