Дооснащение с OkHTTP не установлено Content-Type с @FormUrlEncoded - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь реализовать аутентификацию через x-www-form-urlencoded с Retrofit 2 на Android, но столкнулся с проблемой, что заголовок Content-Type не установлен с аннотацией @FormUrlEncoded, а также я пытаюсь установить его вручную, нокогда я устанавливаю его с опечаткой типа Cotent-Type, она работает правильно, и я вижу ее в заголовках.

Версия дооснащения: 2.4.0

Так что мой вопрос: почему @FormUrlEncodedНе задан тип содержимого, а также @Header аннотация или что можно удалить его из заголовков.

Мой запрос:

   @FormUrlEncoded
   @POST("account/login")
   Single<LoginResponse> login(@Field("memberId") String memberId,
                                    @Field("pin") String pin);

OkHTTP / Retrofit провайдера с перехватчиками:

    @Singleton
@Provides
Retrofit provideRetrofit(final OkHttpClient client, final Moshi moshi) {
    return new Retrofit.Builder()
            .baseUrl(Configuration.BASE_URL)
            .client(client)
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
}

    @Provides
OkHttpClient provideOkHttpClient(@AppContext final Context context) {
    final OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .followRedirects(true)
            .followSslRedirects(true)
            .addInterceptor(createLanguageInterceptor(context));

    if (BuildConfig.DEBUG) {
        builder.addInterceptor(new LoggingInterceptor());
    }

    return builder.build();
}

Interceptor createLanguageInterceptor(@AppContext final Context context) {
    Locale current = context.getResources().getConfiguration().locale;
    return chain -> {
        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("Accept-Language", current.getLanguage());
        Request request = builder.build();
        Response response = chain.proceed(request);
        return response;
    };
}

В качестве обходного пути я реализовал следующий перехватчик:

Interceptor createHeaderTransformationInterceptor() {
    return chain -> {
        final Request request = chain.request();
        String dataType = request.header("Data-Type");
        final Request resultRequest = dataType == null
                ? request
                : chain.request().newBuilder()
                .removeHeader("Data-Type")
                .addHeader("Content-Type", dataType)
                .build();
        return chain.proceed(resultRequest);
    };
}

, и он отлично работает со следующей аннотацией:

@Headers({"Data-Type: application/x-www-form-urlencoded"})

UPD: причина, по которой мой перехватчик не увидел, что это место, где хранится тип контента.Правильный способ увидеть этот заголовок в перехватчике :

    if (requestBody.contentType() != null) {
      logger.log("Content-Type: " + requestBody.contentType());
    }
    if (requestBody.contentLength() != -1) {
      logger.log("Content-Length: " + requestBody.contentLength());
    }

1 Ответ

0 голосов
/ 19 декабря 2018

По этому запросу

@FormUrlEncoded
@POST("account/login")
Single<LoginResponse> login(@Field("memberId") String memberId,
                                        @Field("pin") String pin);

метод @POST и @FormUrlEncoded автоматическое добавление

Content-Type: application/x-www-form-urlencoded в заголовок вы можете проверить в журнале по

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();

            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
                    .connectTimeout(2, TimeUnit.MINUTES)
                    .writeTimeout(2, TimeUnit.MINUTES)
                    .readTimeout(2, TimeUnit.MINUTES)
                    .build();

распечатывает весь журнал в подробном режиме

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...