自 Retrofit 2.0 以来,您有两种选择
1)使用OkHttp 2.2+使用拦截器 https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Interceptor.kt
在 Http 级别,您可以更好地控制请求,因此您可以执行诸如仅将标头应用于向特定端点发出的特定请求等操作。
public class MyOkHttpInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (!"/posts".contains(originalRequest.url()) ) {
return chain.proceed(originalRequest);
}
String token = // get token logic
Request newRequest = originalRequest.newBuilder()
.header("X-Authorization", token)
.build();
return chain.proceed(newRequest);
}
[...]
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.networkInterceptors().add(new MyOkHttpInterceptor());
OkClient okClient = new OkClient(okHttpClient);
YourApi api = new RestAdapter.Builder()
.setEndpoint(url)
.setClient(okClient)
.build()
.create(YourApi.class);
Edit:
添加@杰克沃森 https://stackoverflow.com/users/132047/jake-wharton评论作为另一个选项也是有效的。
2) Put @Header http://square.github.io/retrofit/2.x/retrofit/retrofit2/http/Header.html方法参数上并在调用时将其作为值传递。
来自docs http://square.github.io/retrofit/2.x/retrofit/retrofit2/http/Header.html:
// Replaces the header with the the value of its target.
@GET("/")
void foo(@Header("Accept-Language") String lang, Callback<Response> cb);
标头参数可能为空,这将从请求中省略它们。传递列表或数组将导致每个非空项都有一个标头。
注意:标头不会相互覆盖。所有具有相同名称的标头都将包含在请求中。
EDIT:此选项不应被视为 Retrofit 2.* 放弃了对拦截器的支持。
3)用户改造RequestInterceptor
来自文档:在执行之前拦截每个请求以添加附加数据。
你可以做类似的事情
public class MyRetrofitInterceptor implements RequestInterceptor {
@Override
public void intercept(RequestFacade req) {
String token = // get token logic
if (token != null) {
req.addHeader("X-Authorization", token);
}
}
[...]
YourApi api = new RestAdapter.Builder()
.setEndpoint(url)
.setRequestInterceptor(new MyRetrofitInterceptor())
.build()
.create(YourApi.class);
这种方法的“问题”是拦截器将在所有端点上执行,因为它是在 RestAdapter 级别设置的,而不是每个端点。另外,RequestFacade
不会公开有关请求的太多信息,因此没有机会围绕它添加太多逻辑。