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?

Ashkan Sarlak
la source

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();
dtx12
la source
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'
OWADVL
la source
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();
swetabh suman
la source
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

Avinash Verma
la source
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

voghDev
la source
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.

Gallyamov
la source
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())
    }
}
Nishant Rai
la source
1

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

.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}
Damian JK
la source
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

Mojtaba Razaghi
la source
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()
}
Abu Yousuf
la source