2016-03-04 24 views
5

Stiamo provando a migrare a Retrofit2 e sto riscontrando problemi con un requisito in cui è necessario passare un set di intestazioni generate dinamicamente (utilizzate per l'analisi) per ogni richiesta.Come impostare dinamicamente l'elenco delle intestazioni in Retrofit 2 (Android)

@Headers non è supportato a livello di parametro e poiché il nome del campo dell'intestazione varia in base all'attività corrente, non è possibile utilizzare @Header.

C'è un modo per aggiungere le intestazioni subito prima di eseguire()? (Cercando qualcosa di simile a @ QueryMap/@ FieldMap ma per le intestazioni)

NOTA: Non ho la lista delle intestazioni durante l'inizializzazione del client (e quindi non posso usare l'Interceptor per farlo).

risposta

2

È ancora possibile (e necessario) utilizzare l'intercettore.
Tutto ciò che serve è un po 'di architettura.

Prima creare un helper che fornisca le intestazioni necessarie.

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; 
} 
} 

Tenere un'istanza di questa classe in un luogo accessibile all'interno della vostra app, ad esempio, la MainActivity nostro Application (o, meglio ancora, utilizzare Dependency Injection)

Ora, al momento della creazione della Interceptor basta passare l'istanza del AnalyticsHeader nella Interceptor:

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; 
     } 
} 

E poi ...

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

Ora è possibile modificare il valore dell'intestazione in qualsiasi momento durante il runtime dell'app utilizzando CentralPlaceInApp.getAnalyticsHeader().setHeaderValue(CurrentActivity.class.getSimpleName());