【问题标题】:send JSONObject with POST Request url-encoded with retrofit发送带有 POST 请求 url 编码的 JSONObject 和改造
【发布时间】:2020-04-13 15:34:58
【问题描述】:

我正在使用下面的代码在 JSONObject 中发送参数:

APIClient class

@NonNull
public Retrofit getDefaultClient() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient.Builder()
            .cookieJar(ApiClientCookieJar.getInstance())
            .connectTimeout(Info.connectTimeOut, TimeUnit.SECONDS)
            .readTimeout(Info.readTimeOut, TimeUnit.SECONDS)
            .writeTimeout(Info.writeTimeOut, TimeUnit.SECONDS)
            .addInterceptor(chain -> {
                Request request = chain.request().newBuilder()
                        .addHeader("Accept", "application/json")
                        .addHeader("Content-Type", " application/json")
                        .build();
                if (AppData.getInstance().getToken() != null && !AppData.getInstance().getToken().isEmpty()) {
                    request = request.newBuilder()
                            .addHeader("token", AppData.getInstance().getToken())
                            .build();
                }
                return chain.proceed(request);
            })
            .addNetworkInterceptor(interceptor)
            .build();
    Gson gson = new GsonBuilder()
            .setLenient()
            .create();
    return new Retrofit.Builder()
            .baseUrl(Info.webserver_url_V2)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client)
            .build();
}

APIInterface interface

@FormUrlEncoded
@POST(Info.req_v2_search)
Observable<Response<String>> search(@FieldMap Map<String, String> fields);

@FormUrlEncoded
@POST(Info.req_v2_search)
Observable<Response<String>> search(@Body String body);

@FormUrlEncoded
@POST(Info.req_v2_search)
Observable<Response<String>> search(@Body RequestBody requestBody);

Presenter class

    // solution 1 : using FieldMap
    @FieldMap Map<String, String> fields; // Injest
    // solution 2 : MultipartBody
    MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);
    for (String key : fields.keySet()) {
        builder.addFormDataPart(key, Objects.requireNonNull(fields.get(key)));
    }
    MultipartBody multipartBody = builder.build();
    // solution 3 : RequestBody and Json string
    JsonObject sendJsonObject = new JsonObject();
    for (String key : fields.keySet()) {
        sendJsonObject.addProperty(key, Objects.requireNonNull(fields.get(key)));
    }
    RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), sendJsonObject.toString());

但没用

下面的邮递员输出cUrl code 工作正常:

curl --location --request POST 'http://caltech.cntxts.com/v2/search' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: session=FfFHW9bWbcBQ1W0eoV3KTg.J4vQaa4pQdgIzoIRcyCXJuFHVSpXaLvn-8W-ViWugNXmWGt66aTBj3zu8QzrZ9coLnDKCNYRpQNz49WqyuOY5kAEYzuTmO85dKYXPbeS3-Q.1586289772575.31536000000.3PFNma6gTSQ63X-6MJweuJXctYvGLf8_-3Qbj8z8S5E' \
--data-urlencode 'type=product' \
--data-urlencode 'viewMode=0'

【问题讨论】:

    标签: android post http-post retrofit2 url-parameters


    【解决方案1】:

    您将在 interceptor 的标头中添加 Content-Type", " application/json,这将重写请求,因此只需删除

    .addHeader("Content-Type", " application/json")
    

    作为

    OkHttpClient client = new OkHttpClient.Builder()
                .cookieJar(ApiClientCookieJar.getInstance())
                .connectTimeout(Info.connectTimeOut, TimeUnit.SECONDS)
                .readTimeout(Info.readTimeOut, TimeUnit.SECONDS)
                .writeTimeout(Info.writeTimeOut, TimeUnit.SECONDS)
                .addInterceptor(chain -> {
                    Request request = chain.request().newBuilder()
                            .addHeader("Accept", "application/json")
    //                      .addHeader("Content-Type", " application/json") //remove 
                            .build();
                    if (AppData.getInstance().getToken() != null && !AppData.getInstance().getToken().isEmpty()) {
                        request = request.newBuilder()
                                .addHeader("token", AppData.getInstance().getToken())
                                .build();
                    }
                    return chain.proceed(request);
                })
                .addNetworkInterceptor(interceptor)
                .build();
    

    【讨论】:

      【解决方案2】:

      你需要这样发送请求,在API接口类中添加这个:

      @Headers("Content-Type: application/json")
      @POST("{endpoint}")
      Observable<Response<String>> hitAPI(@Body JsonObject object);
      

      为其添加标头并从标头中删除此.addHeader("Content-Type", " application/json"),并根据所需类型将其单独添加到API接口类中的每个请求中。

      【讨论】:

      • 谢谢,在服务器端进行一些更改后,它工作正常
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 2020-01-06
      • 2020-09-08
      • 2021-12-13
      • 1970-01-01
      • 2013-10-06
      相关资源
      最近更新 更多