Menambahkan header ke semua permintaan dengan Retrofit 2

130

Dokumentasi Retrofit 2 mengatakan:

Header yang perlu ditambahkan ke setiap permintaan dapat ditentukan menggunakan pencegat OkHttp.

Itu dapat dilakukan dengan mudah menggunakan versi sebelumnya, inilah QA terkait.

Tetapi menggunakan retrofit 2, saya tidak dapat menemukan sesuatu seperti setRequestInterceptoratau setInterceptormetode yang dapat diterapkan pada Retrofit.Builderobjek.

Juga tampaknya tidak ada lagi RequestInterceptordi OkHttp . Dokumen Retrofit merujuk kita ke Interceptor yang saya tidak begitu mengerti bagaimana menggunakannya untuk tujuan ini.

Bagaimana saya bisa melakukan ini?

Ashkan Sarlak
sumber

Jawaban:

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
sumber
5
Dalam versi retrofit2-beta3 sedikit berbeda. Lihat di sini: stackoverflow.com/questions/34973432/…
Ashkan Sarlak
Bagaimana kami dapat memastikan bahwa tajuk ini telah dikirim. Saat saya men-debug saat Panggilan, enqueuesaya tidak dapat melihat header default.
viper
Seharusnya new OkHttpClient.Builder()malahnew OkHttpClient()
Wojtek
80

Versi Retrofit Terbaru DI SINI -> 2.1.0.

versi lambda:

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

versi panjang jelek:

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

versi lengkap:

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

file gradle (Anda perlu menambahkan interseptor logging jika Anda berencana menggunakannya):

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

Untuk Logging permintaan dan respons Anda, Anda memerlukan interseptor dan juga untuk mengatur header Anda memerlukan interseptor, Inilah solusi untuk menambahkan interseptor sekaligus menggunakan 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;

    }

Sekarang di objek retrofit Anda, tambahkan header ini di klien

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

Coba tajuk jenis ini untuk Retrofit 1.9 dan 2.0. Untuk Jenis Konten Json.

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

Anda dapat menambahkan lebih banyak tajuk yaitu

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

Tambahkan ke header secara dinamis:

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

Panggil Anda metode yaitu

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

Atau

Ingin melewati setiap kemudian Buat objek HttpClient dengan 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());
            }
        });

Kemudian tambahkan ke objek retrofit

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

UPDATE jika Anda menggunakan Kotlin, hapus yang { }lain itu tidak akan berfungsi

Avinash Verma
sumber
2
Bagaimana cara membuat satu tajuk untuk semua permintaan di antarmuka tanpa menduplikasinya?
Evgenii Vorobei
Anda harus menambahkannya di interseptor Pencatatan HTTP
Avinash Verma
6

Dalam kasus saya addInterceptor()tidak berhasil menambahkan header HTTP ke permintaan saya, saya harus menggunakan addNetworkInterceptor(). Kode adalah sebagai berikut:

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

Dan kode interseptor:

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

Ini dan lebih banyak contoh tentang inti ini

voghDev
sumber
5

Jika Anda menggunakan metode addInterceptor untuk menambahkan HttpLoggingInterceptor, metode ini tidak akan mencatat hal-hal yang ditambahkan oleh interseptor lain yang diterapkan setelah HttpLoggingInterceptor.

Misalnya: Jika Anda memiliki dua interseptor "HttpLoggingInterceptor" dan "AuthInterceptor", serta HttpLoggingInterceptor yang diterapkan terlebih dahulu, Anda tidak dapat melihat http-params atau header yang disetel oleh AuthInterceptor.

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

Saya menyelesaikannya, melalui menggunakan metode addNetworkInterceptor.

Gallyamov
sumber
1
Anda juga dapat menambahkan HttpLoggingInterceptorsebagai pencegat terakhir untuk melihat permintaan akhir.
Micer
2

Gunakan Klien Retrofit ini

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

Saya meneruskan JWT bersama dengan setiap permintaan. Harap tidak keberatan dengan nama variabel, ini agak membingungkan.

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

Di kotlin menambahkan interseptor terlihat seperti itu:

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

Pustaka RetrofitHelper yang ditulis dalam kotlin, akan memungkinkan Anda melakukan panggilan API, menggunakan beberapa baris kode.

Tambahkan header di kelas aplikasi Anda seperti ini:

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

        }
    }  

Dan kemudian lakukan panggilan Anda:

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)

Untuk informasi lebih lanjut, lihat dokumentasi

Mojtaba Razaghi
sumber
0

Versi Kotlin akan menjadi

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
sumber