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


130

La documentation de Retrofit 2 dit:

Les en-têtes qui doivent être ajoutés à chaque requête 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 en utilisant retrofit 2, je n'ai pas trouvé quelque chose comme setRequestInterceptorou une setInterceptorméthode qui puisse être appliquée à un Retrofit.Builderobjet.

De plus, il semble qu'il n'y RequestInterceptoren ait plus dans OkHttp . La documentation de Retrofit nous renvoie à Interceptor que je ne comprenais pas très bien comment l'utiliser à cette fin.

Comment puis-je faire ceci?

Réponses:


201
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();

5
Dans la version retrofit2-beta3, c'est un peu différent. Voir ici: stackoverflow.com/questions/34973432/…
Ashkan Sarlak

Comment pouvons-nous confirmer que ces en-têtes sont envoyés. Lorsque je débogue à l'appel, enqueueje ne vois pas les en-têtes par défaut.
vipère

Cela devrait être à la new OkHttpClient.Builder()placenew OkHttpClient()
Wojtek

80

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

version lambda:

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

vilaine version longue:

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

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'

13

Pour enregistrer votre demande et votre réponse, vous avez besoin d'un intercepteur et également pour définir l'en-tête, vous avez besoin d'un intercepteur, voici la solution pour ajouter à la fois l'intercepteur à la fois en utilisant la modernisation 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 rénovation, ajoutez cet en-tête dans le client

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

12

Essayez ce type d'en-tête pour Retrofit 1.9 et 2.0. Pour le type de contenu Json.

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

Vous pouvez ajouter beaucoup plus d'en-têtes, c'est-à-dire

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

Ajouter dynamiquement aux en-têtes:

@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);

Appelez votre méthode ie

mAPI.addToPlayList("application/json", playListParam);

Ou

Vous voulez passer à chaque fois, puis créer un objet HttpClient avec http Interceptor:

OkHttpClient httpClient = new OkHttpClient();
        httpClient.networkInterceptors().add(new Interceptor() {
            @Override
            public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.header("Content-Type", "application/json");
                return chain.proceed(requestBuilder.build());
            }
        });

Puis ajouter à l'objet de mise à niveau

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(httpClient).build();

MISE À JOUR si vous utilisez Kotlin, supprimez { }sinon cela ne fonctionnera pas


2
Comment créer un en-tête pour toutes les demandes dans l'interface sans le dupliquer?
Evgenii Vorobei

Vous devez l'ajouter dans l'intercepteur de journalisation HTTP
Avinash Verma

6

Dans mon cas, cela addInterceptor()n'a pas fonctionné pour ajouter des en-têtes HTTP à ma demande, j'ai dû utiliser addNetworkInterceptor(). Le code est le suivant:

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

Et le code de l'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 ce point essentiel


5

Si vous utilisez la méthode addInterceptor pour ajouter HttpLoggingInterceptor, il ne consignera pas les éléments ajoutés par d'autres intercepteurs appliqués plus tard que HttpLoggingInterceptor.

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

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

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


1
Vous pouvez également ajouter HttpLoggingInterceptorcomme dernier intercepteur pour voir la demande finale.
Micer

2

Utilisez ce client de rénovation

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. Ne vous inquiétez pas des 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())
    }
}

1

Dans kotlin, l'ajout d'intercepteur ressemble à ceci:

.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}

0

La bibliothèque RetrofitHelper écrite en kotlin, vous permettra de faire des appels API, en utilisant quelques lignes de code.

Ajoutez des en-têtes dans votre classe d'application comme ceci:

class Application : Application() {

    override fun onCreate() {
    super.onCreate()

        retrofitClient = RetrofitClient.instance
                    //api url
                .setBaseUrl("https://reqres.in/")
                    //you can set multiple urls
        //                .setUrl("example","http://ngrok.io/api/")
                    //set timeouts
                .setConnectionTimeout(4)
                .setReadingTimeout(15)
                    //enable cache
                .enableCaching(this)
                    //add Headers
                .addHeader("Content-Type", "application/json")
                .addHeader("client", "android")
                .addHeader("language", Locale.getDefault().language)
                .addHeader("os", android.os.Build.VERSION.RELEASE)
            }

        companion object {
        lateinit var retrofitClient: RetrofitClient

        }
    }  

Et puis passez votre appel:

retrofitClient.Get<GetResponseModel>()
            //set path
            .setPath("api/users/2")
            //set url params Key-Value or HashMap
            .setUrlParams("KEY","Value")
            // you can add header here
            .addHeaders("key","value")
            .setResponseHandler(GetResponseModel::class.java,
                object : ResponseHandler<GetResponseModel>() {
                    override fun onSuccess(response: Response<GetResponseModel>) {
                        super.onSuccess(response)
                        //handle response
                    }
                }).run(this)

Pour plus d'informations, consultez la documentation


0

La version Kotlin serait

fun getHeaderInterceptor():Interceptor{
    return object : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val request =
            chain.request().newBuilder()
                    .header(Headers.KEY_AUTHORIZATION, "Bearer.....")
                    .build()
            return chain.proceed(request)
        }
    }
}


private fun createOkHttpClient(): OkHttpClient {
    return OkHttpClient.Builder()
            .apply {
                if(BuildConfig.DEBUG){
                    this.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
                }
            }
            .addInterceptor(getHeaderInterceptor())
            .build()
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.