Retrofit2/OkHttp 重写覆盖headers 与 不重写覆盖Headers

台风海马来深圳了,下面的虽然是英文,但是感觉比中文更容易让人看懂

Add Request Headers

Adding HTTP request headers is a good practice to add information for API requests. A common example is authorization using the Authorization header field. If you need the header field including its value on almost every request, you can use an interceptor to add this piece of information. This way, you don’t need to add the @Header annotation to every endpoint declaration.

OkHttp interceptors offer two ways to add header fields and values. You can either override existing headers with the same key or just add them without checking if there is another header key-value-pair already existing. We’ll walk you through both of them in the following paragraphs.

How to Override Headers

Intercepting HTTP requests with the help of OkHttp interceptors allows you to manipulate the actual request and apply your customization. The request builder has a .header(key, val) method which will add your defined header to the request. If there is already an existing header with the same key identifier, this method will override the previously defined value.

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();  
httpClient.addInterceptor(new Interceptor() {  
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        // Request customization: add request headers
        Request.Builder requestBuilder = original.newBuilder()
                .header("Authorization", "auth-value"); // <-- this is the important line

        Request request = requestBuilder.build();
        return chain.proceed(request);
    }
});

OkHttpClient client = httpClient.build();  
```

Retrofit, and especially OkHttp, allow you to add multiple headers with the same key. The .header method will replace all existing headers with the defined key identifier. Within the code snippet above, every Authorization header (if multiple have been defined already) will be updated and their previous value will be replaced with auth-value.

# How to Not Override Headers
There are situations where multiple headers with the same name are used. Actually, we’re only aware of one specific example from practise: the Cache-Control header. The HTTP RFC2616 specifies that multiple header values with the same name are allowed if they can be stated as a comma-separated list.

That means,
```
Cache-Control: no-cache  
Cache-Control: no-store  
```
is the same as
```
Cache-Control: no-cache, no-store  
```
Using Retrofit 2 and an OkHttp interceptor, you can add multiple request headers with the same key. The method you need to use is .addHeader.

The following example will add the Cache-Control headers from the example above:

```
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();  
httpClient.addInterceptor(new Interceptor() {  
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        // Request customization: add request headers
        Request.Builder requestBuilder = original.newBuilder()
                    .addHeader("Cache-Control", "no-cache")
                    .addHeader("Cache-Control", "no-store");

        Request request = requestBuilder.build();
        return chain.proceed(request);
    }
});

OkHttpClient client = httpClient.build();  
```
# Take Away
Notice the small but mighty difference:

- .header(key, val): will override preexisting headers identified by key
- .addHeader(key, val): will add the header and don’t override preexisting ones

Make sure you’re using the appropriate method to achieve your desired request results.

# Outlook
This post walked you through the different methods on how to add request headers using OkHttp’s request interceptors. Customizing the request and adding request header enable a simple and effective way to pass data with every request. This method will result in much cleaner code than adding header fields with the [@Header](https://my.oschina.net/header) annotation for every request.

转载于:https://my.oschina.net/zengliubao/blog/761424

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用RxJava2 + Retrofit2 + OKHttp进行POST请求,可以按照以下步骤进行: 1. 添加依赖 在项目的build.gradle文件中添加以下依赖: ``` dependencies { implementation 'io.reactivex.rxjava2:rxjava:2.2.19' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:okhttp:4.9.1' } ``` 2. 创建Service接口 创建一个接口,用于定义POST请求的方法。例如: ``` public interface ApiService { @POST("login") Observable<LoginResponse> login(@Body LoginRequest request); } ``` 3. 创建Retrofit对象 在Application类或其他初始化类中,创建Retrofit对象: ``` public class MyApp extends Application { private static ApiService apiService; @Override public void onCreate() { super.onCreate(); // 创建OkHttpClient对象 OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .build(); // 创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/api/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); apiService = retrofit.create(ApiService.class); } public static ApiService getApiService() { return apiService; } } ``` 4. 发起POST请求 在需要发起POST请求的地方,可以使用以下代码: ``` LoginRequest request = new LoginRequest(); request.setUsername("admin"); request.setPassword("123456"); MyApp.getApiService().login(request) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<LoginResponse>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(LoginResponse response) { // 处理响应数据 } @Override public void onError(Throwable e) { // 处理异常 } @Override public void onComplete() { } }); ``` 上述代码中,我们首先创建了一个LoginRequest对象,用于存储要发送的数据。然后调用MyApp.getApiService().login(request)方法,发起POST请求。在这里,我们使用了RxJava2的Observable对象,将请求结果封装为一个可观察对象。使用subscribeOn(Schedulers.io())指定在IO线程中进行网络请求,使用observeOn(AndroidSchedulers.mainThread())指定在主线程中处理响应。最后通过subscribe方法订阅请求结果,处理响应数据或异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值