Как динамически установить список заголовков в Retrofit 2 (Android)

Мы пытаемся перейти на использование Retrofit2, и у меня возникают проблемы с требованием, когда нам нужно передавать набор динамически генерируемых заголовков (используемых для аналитики) для каждого запроса.

@Headers не поддерживается на уровне параметров, и, поскольку имя поля заголовка зависит от текущей активности, я не могу использовать @Header.

Есть ли способ добавить заголовки непосредственно перед execute()? (Ищу что-то похожее на @QueryMap/@FieldMap, но для заголовков)

ПРИМЕЧАНИЕ. У меня нет списка заголовков при инициализации клиента (и, следовательно, я не могу использовать Interceptor для этого).


person p-pat-ni    schedule 04.03.2016    source источник


Ответы (1)


Вы по-прежнему можете (и должны) использовать Interceptor.
Все, что вам нужно, это немного архитектуры.

Сначала создайте помощник, который предоставляет необходимые заголовки.

public class AnalyticsHeader {
 private String analyticsHeaderName;
 private String analyticsHeaderValue;

 public void setHeaderValue(String header) {
   this.analyticsHeaderValue = header;
 } 

 public void setHeaderName(String header) {
   this.analyticsHeaderName = header;
 } 

 public String getHeaderName() { 
  return analyticsHeaderName;
 }
 public String getHeaderValue() { 
  return analyticsHeaderValue;
 }
}

Держите экземпляр этого класса в доступном месте внутри вашего приложения, например, MainActivity нашего приложения (или, что еще лучше, используйте внедрение зависимостей)

Теперь, после создания перехватчика, просто передайте экземпляр AnalyticsHeader в перехватчик:

public static final class AnalyticsInterceptor implements Interceptor {
        private final AnalyticsHeader header;

        public AnalyticsInterceptor(AnalyticsHeader header) {
            this.header = header;
        }

        @Override
        public Response intercept(Chain chain) throws IOException {
            final Request original = chain.request();
            Response response;
            if (header.getHeader() != null) {
                 Request request = original.newBuilder()
                        .header(header.getHeaderName(), header.getHeaderValue())
                        .method(original.method(), original.body())
                        .build();
                 response = chain.proceed(request);
            } else {
                response = chain.proceed(original);
            }

         return response;
       }
 }

А потом...

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new AnalyticsInterceptor(CentralPlaceInApp.getAnalyticsHeader());
...
retrofit = new Retrofit.Builder()
                .baseUrl(config.getRestUrl())
                .client(builder.build())
                .build();

Теперь вы можете изменить значение заголовка в любое время во время выполнения приложения, используя CentralPlaceInApp.getAnalyticsHeader().setHeaderValue(CurrentActivity.class.getSimpleName());

person Lovis    schedule 20.06.2016