Hinzufügen eines Headers zu allen Anforderungen mit Retrofit 2

128

In der Dokumentation von Retrofit 2 heißt es:

Header, die zu jeder Anforderung hinzugefügt werden müssen, können mithilfe eines OkHttp-Interceptors angegeben werden.

Dies kann problemlos mit der vorherigen Version durchgeführt werden. Hier ist die zugehörige Qualitätssicherung.

Aber der Einsatz von Retrofit - 2, kann ich nicht so etwas wie finden setRequestInterceptoroder setInterceptorVerfahren, die angewandt werden kann Retrofit.BuilderObjekt.

Es scheint auch, dass es RequestInterceptorin OkHttp keine mehr gibt. Retrofits Dokument verweist uns auf Interceptor, dass ich nicht ganz verstanden habe, wie man es für diesen Zweck verwendet.

Wie kann ich das machen?

Ashkan Sarlak
quelle

Antworten:

199
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
quelle
5
In der Retrofit2-Beta3-Version ist das etwas anders. Siehe hier: stackoverflow.com/questions/34973432/…
Ashkan Sarlak
Wie können wir bestätigen, dass diese Header gesendet werden? Beim Debuggen bei Anruf werden enqueuedie Standardheader nicht angezeigt.
Viper
Es sollte new OkHttpClient.Builder()stattdessen seinnew OkHttpClient()
Wojtek
80

Die neueste Nachrüstversion gibt es HIER -> 2.1.0.

Lambda-Version:

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

hässliche lange Version:

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

Vollversion:

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-Datei (Sie müssen den Protokollierungs-Interceptor hinzufügen, wenn Sie ihn verwenden möchten):

  //----- 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
quelle
13

Zum Protokollieren Ihrer Anfrage und Antwort benötigen Sie einen Interceptor und zum Festlegen des Headers benötigen Sie einen Interceptor. Hier ist die Lösung, um beide Interceptor mithilfe von Retrofit 2.1 gleichzeitig hinzuzufügen

 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;

    }

Fügen Sie nun in Ihrem Nachrüstobjekt diesen Header im Client hinzu

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

Versuchen Sie diesen Headertyp für Retrofit 1.9 und 2.0. Für Json-Inhaltstyp.

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

Sie können viel mehr Überschriften hinzufügen, z

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

Dynamisch zu Headern hinzufügen:

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

Nennen Sie Methode dh

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

Oder

Möchten Sie jedes Mal übergeben, dann erstellen Sie ein HttpClient-Objekt mit 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());
            }
        });

Dann zum Nachrüstobjekt hinzufügen

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

UPDATE Wenn Sie Kotlin verwenden, entfernen Sie das, { }sonst funktioniert es nicht

Avinash Verma
quelle
2
Wie erstelle ich einen Header für alle Anforderungen in der Schnittstelle, ohne ihn zu duplizieren?
Evgenii Vorobei
Sie müssen es in HTTP Logging Interceptor
Avinash Verma
6

In meinem Fall addInterceptor()funktionierte es nicht, HTTP-Header zu meiner Anfrage hinzuzufügen, ich musste verwenden addNetworkInterceptor(). Der Code lautet wie folgt:

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

Und der Abfangcode:

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

Dies und weitere Beispiele zu diesem Kern

voghDev
quelle
5

Wenn Sie die addInterceptor-Methode zum Hinzufügen von HttpLoggingInterceptor verwenden, werden nicht die Dinge protokolliert, die von anderen Interceptors hinzugefügt wurden, die später als HttpLoggingInterceptor angewendet wurden.

Beispiel: Wenn Sie zwei Interceptors "HttpLoggingInterceptor" und "AuthInterceptor" und HttpLoggingInterceptor zuerst angewendet haben, können Sie die von AuthInterceptor festgelegten http-Parameter oder Header nicht anzeigen.

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

Ich habe es mithilfe der addNetworkInterceptor-Methode gelöst.

Gallyamov
quelle
1
Sie können auch HttpLoggingInterceptorals letzter Interceptor hinzufügen , um die endgültige Anforderung anzuzeigen.
Micer
2

Verwenden Sie diesen Retrofit-Client

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

Ich gebe das JWT zusammen mit jeder Anfrage weiter. Bitte beachten Sie die Variablennamen nicht, es ist etwas verwirrend.

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
quelle
1

In Kotlin sieht das Hinzufügen von Interceptor folgendermaßen aus:

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

Mit der in kotlin geschriebenen RetrofitHelper- Bibliothek können Sie API-Aufrufe mit wenigen Codezeilen durchführen.

Fügen Sie Ihrer Anwendungsklasse folgende Header hinzu:

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

        }
    }  

Und dann rufen Sie an:

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)

Weitere Informationen finden Sie in der Dokumentation

Mojtaba Razaghi
quelle
0

Kotlin-Version wäre

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
quelle