2016-03-04 1 views
5

Nous essayons de migrer vers Retrofit2 et j'ai des problèmes avec une exigence où nous devons transmettre un ensemble d'en-têtes générés dynamiquement (utilisés pour l'analyse) pour chaque demande.Comment faire pour définir dynamiquement la liste des en-têtes dans Retrofit 2 (Android)

@Headers n'est pas pris en charge au niveau du paramètre et comme le nom du champ d'en-tête varie en fonction de l'activité en cours, je ne peux pas utiliser @Header.

Y at-il un moyen d'ajouter les en-têtes juste avant d'exécuter()? (Vous cherchez quelque chose de similaire à @ QueryMap/@ FieldMap mais pour les en-têtes)

REMARQUE: Je n'ai pas la liste des en-têtes lors de l'initialisation du client (et je ne peux donc pas utiliser l'Interceptor pour cela).

Répondre

2

Vous pouvez toujours (et devez) utiliser l'Interceptor.
Tout ce dont vous avez besoin est d'un peu d'architecture.

Créez d'abord un assistant qui fournit les en-têtes nécessaires.

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

Gardez une instance de cette classe dans un endroit accessible à l'intérieur de votre application, par exemple MainActivity notre l'application (ou mieux encore, utiliser Dependency Injection)

Maintenant, lors de la création de l'Interceptor juste passer l'instance du AnalyticsHeader dans l'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; 
     } 
} 

Et puis ...

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

Maintenant, vous pouvez modifier la valeur de l'en-tête à tout moment pendant l'exécution de votre application en utilisant CentralPlaceInApp.getAnalyticsHeader().setHeaderValue(CurrentActivity.class.getSimpleName());