Thêm tiêu đề cho tất cả yêu cầu với Retrofit 2


128

Tài liệu của Retrofit 2 nói:

Các tiêu đề cần được thêm vào mỗi yêu cầu có thể được chỉ định bằng cách sử dụng bộ chặn OkHttp.

Nó có thể được thực hiện dễ dàng bằng phiên bản trước, đây là QA liên quan.

Nhưng sử dụng trang bị thêm 2, tôi không thể tìm thấy một cái gì đó giống như setRequestInterceptorhoặc setInterceptorphương pháp có thể được áp dụng cho Retrofit.Builderđối tượng.

Ngoài ra, dường như không còn RequestInterceptortrong OkHttp nữa. Tài liệu của Retrofit giới thiệu chúng tôi với Interceptor mà tôi không hiểu lắm về cách sử dụng nó cho mục đích này.

Tôi có thể làm cái này như thế nào?

Câu trả lời:


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

5
Trong phiên bản retrofit2-beta3, nó hơi khác một chút. Xem tại đây: stackoverflow.com/questions/34973432/
Ấn

Làm thế nào chúng ta có thể xác nhận rằng những tiêu đề này được gửi. Khi tôi gỡ lỗi trên Call enqueuetôi không thể thấy các tiêu đề mặc định.
viper

Nó nên được new OkHttpClient.Builder()thay thếnew OkHttpClient()
Wojtek

80

Phiên bản trang bị thêm mới nhất TẠI ĐÂY -> 2.1.0.

phiên bản lambda:

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

phiên bản dài xấu xí:

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

phiên bản đầy đủ:

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

tập tin gradle (bạn cần thêm bộ chặn ghi nhật ký nếu bạn định sử dụng nó):

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

Để ghi nhật ký yêu cầu và phản hồi của bạn, bạn cần một thiết bị chặn và cũng để thiết lập tiêu đề bạn cần một thiết bị chặn, Đây là giải pháp để thêm cả hai thiết bị chặn cùng một lúc bằng cách sử dụng thêm 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;

    }

Bây giờ trong đối tượng trang bị thêm của bạn thêm tiêu đề này trong máy khách

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

12

Hãy thử tiêu đề loại này cho Retrofit 1.9 và 2.0. Đối với loại nội dung Json.

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

Bạn có thể thêm nhiều tiêu đề tức là

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

Tự động thêm vào tiêu đề:

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

Gọi cho bạn phương thức tức là

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

Hoặc là

Muốn vượt qua mọi lúc thì hãy tạo đối tượng HttpClient bằng 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());
            }
        });

Sau đó thêm vào đối tượng trang bị thêm

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

CẬP NHẬT nếu bạn đang sử dụng Kotlin, hãy loại bỏ { }nó nếu không nó sẽ không hoạt động


2
Làm cách nào để tạo một tiêu đề cho tất cả các yêu cầu trong giao diện mà không cần sao chép nó?
Evgenii Vorobei

Bạn phải thêm nó vào bộ chặn đánh chặn HTTP Logging
Avinash Verma

6

Trong trường hợp của tôi addInterceptor()không hoạt động để thêm tiêu đề HTTP vào yêu cầu của tôi, tôi đã phải sử dụng addNetworkInterceptor(). Mã như sau:

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

Và mã đánh chặn:

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

Đây và nhiều ví dụ về ý chính này


5

Nếu bạn sử dụng phương thức addInterceptor để thêm httpLoggingInterceptor, thì nó sẽ không ghi lại những thứ được thêm bởi các bộ chặn khác được áp dụng muộn hơn so với HttpLoggingInterceptor.

Ví dụ: Nếu bạn có hai thiết bị chặn "HttpLoggingInterceptor" và "AuthInterceptor" và httpLoggingInterceptor được áp dụng trước, thì bạn không thể xem http-params hoặc tiêu đề do AuthInterceptor đặt.

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

Tôi đã giải quyết nó, thông qua việc sử dụng phương thức addNetworkInterceptor.


1
Bạn cũng có thể thêm HttpLoggingInterceptorlàm người chặn cuối cùng để xem yêu cầu cuối cùng.
Micer

2

Sử dụng khách hàng trang bị thêm này

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

Tôi đang vượt qua JWT cùng với mọi yêu cầu. Xin đừng bận tâm đến các tên biến, nó hơi khó hiểu.

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

Trong kotlin thêm đánh chặn trông như vậy:

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

0

Thư viện RetrofitHelper được viết bằng kotlin, sẽ cho phép bạn thực hiện các cuộc gọi API, sử dụng một vài dòng mã.

Thêm các tiêu đề trong lớp ứng dụng của bạn như thế này:

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

        }
    }  

Và sau đó thực hiện cuộc gọi của bạn:

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)

Để biết thêm thông tin xem tài liệu


0

Phiên bản Kotlin sẽ là

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()
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.