web-dev-qa-db-fra.com

Ajout d'un en-tête à toutes les demandes avec Retrofit 2

La documentation de Retrofit 2 dit:

Les en-têtes devant être ajoutés à chaque demande peuvent être spécifiés à l'aide d'un intercepteur OkHttp.

Cela peut être fait facilement en utilisant la version précédente, voici le QA associé.

Mais avec retrofit 2, je ne pouvais pas trouver quelque chose comme la méthode setRequestInterceptor ou setInterceptor qui puisse être appliquée à l’objet Retrofit.Builder.

De plus, il semble qu'il n'y ait pas de RequestInterceptor dans OkHttp more. Le document de Retrofit nous renvoie à Interceptor que je ne comprenais pas trop comment l'utiliser à cette fin.

Comment puis-je faire ceci?

90
Ashkan Sarlak
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

httpClient.addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
        return chain.proceed(request);
    }
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();
143
dtx12

La dernière version de rattrapage ICI -> 2.1.0.

version lambda:

  builder.addInterceptor(chain -> {
    Request request = chain.request().newBuilder().addHeader("key", "value").build();
    return chain.proceed(request);
  });

Version longue laide:

  builder.addInterceptor(new Interceptor() {
    @Override public Response intercept(Chain chain) throws IOException {
      Request request = chain.request().newBuilder().addHeader("key", "value").build();
      return chain.proceed(request);
    }
  });

version complète:

class Factory {

public static APIService create(Context context) {

  OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
  builder.readTimeout(10, TimeUnit.SECONDS);
  builder.connectTimeout(5, TimeUnit.SECONDS);

  if (BuildConfig.DEBUG) {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
    builder.addInterceptor(interceptor);
  }

  builder.addInterceptor(chain -> {
    Request request = chain.request().newBuilder().addHeader("key", "value").build();
    return chain.proceed(request);
  });

  builder.addInterceptor(new UnauthorisedInterceptor(context));
  OkHttpClient client = builder.build();

  Retrofit retrofit =
      new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

  return retrofit.create(APIService.class);
  }
}

fichier gradle (vous devez ajouter l'intercepteur de journalisation si vous prévoyez de l'utiliser):

  //----- Retrofit
  compile 'com.squareup.retrofit2:retrofit:2.1.0'
  compile "com.squareup.retrofit2:converter-gson:2.1.0"
  compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
  compile 'com.squareup.okhttp3:logging-interceptor:3.4.0'
61
OWADVL

Pour consigner votre demande et votre réponse, vous avez besoin d'un intercepteur et pour définir l'en-tête, vous avez besoin d'un intercepteur. Voici la solution pour ajouter l'intercepteur simultanément en utilisant retrofit 2.1

 public OkHttpClient getHeader(final String authorizationValue ) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .addNetworkInterceptor(
                        new Interceptor() {
                            @Override
                            public Response intercept(Interceptor.Chain chain) throws IOException {
                                Request request = null;
                                if (authorizationValue != null) {
                                    Log.d("--Authorization-- ", authorizationValue);

                                    Request original = chain.request();
                                    // Request customization: add request headers
                                    Request.Builder requestBuilder = original.newBuilder()
                                            .addHeader("Authorization", authorizationValue);

                                    request = requestBuilder.build();
                                }
                                return chain.proceed(request);
                            }
                        })
                .build();
        return okClient;

    }

Maintenant, dans votre objet de modernisation, ajoutez cet en-tête dans le client

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .client(getHeader(authorizationValue))
                .addConverterFactory(GsonConverterFactory.create())
                .build();
11
swetabh suman

J'ai trouvé un autre moyen de Retrofit 1.9 et 2.0, pour Json Content Type.

@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);

Vous pouvez ajouter de nombreux autres en-têtes, i.e

@Headers({
        "Accept: application/json",
        "User-Agent: Your-App-Name",
        "Cache-Control: max-age=640000"
    })
6
Avinash Verma

Dans mon cas, addInterceptor()ne fonctionnait pas pour ajouter des en-têtes HTTP à ma demande, je devais utiliser addNetworkInterceptor(). Le code est le suivant:

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new AddHeaderInterceptor());

Et le code d'intercepteur:

public class AddHeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("Authorization", "MyauthHeaderContent");

        return chain.proceed(builder.build());
    }
}

Ceci et d’autres exemples sur this Gist

5
voghDev

Si vous utilisez la méthode addInterceptor pour ajouter HttpLoggingInterceptor, il n'enregistrera pas les éléments ajoutés par d'autres intercepteurs appliqués ultérieurement à HttpLoggingInterceptor.

Par exemple: Si vous avez deux intercepteurs "HttpLoggingInterceptor" et "AuthInterceptor" et que HttpLoggingInterceptor est appliqué en premier, vous ne pouvez pas afficher les paramètres http ou en-têtes définis par AuthInterceptor.

OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());

Je l'ai résolu, en utilisant la méthode addNetworkInterceptor.

4
Gallyamov

Utiliser ce client de modernisation 

class RetrofitClient2(context: Context) : OkHttpClient() {

    private var mContext:Context = context
    private var retrofit: Retrofit? = null

    val client: Retrofit?
        get() {
            val logging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)

            val client = OkHttpClient.Builder()
                    .connectTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
                    .readTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
                    .writeTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
            client.addInterceptor(logging)
            client.interceptors().add(AddCookiesInterceptor(mContext))

            val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
            if (retrofit == null) {

                retrofit = Retrofit.Builder()
                        .baseUrl(Constants.URL)
                        .addConverterFactory(GsonConverterFactory.create(gson))
                        .client(client.build())
                        .build()
            }
            return retrofit
        }
}

Je passe le JWT avec chaque demande. S'il vous plaît ne faites pas attention aux noms de variables, c'est un peu déroutant. 

class AddCookiesInterceptor(context: Context) : Interceptor {
    val mContext: Context = context
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val builder = chain.request().newBuilder()
        val preferences = CookieStore().getCookies(mContext)
        if (preferences != null) {
            for (cookie in preferences!!) {
                builder.addHeader("Authorization", cookie)
            }
        }
        return chain.proceed(builder.build())
    }
}
0
Nishant Rai