我们正在尝试迁移到使用Retrofit2,而我遇到的问题是我们需要为每个请求传递一组动态生成的标头(用于分析)。
参数级别不支持@Headers,因为标题字段名称因当前活动而异,所以我不能使用@Header。有没有办法在execute()之前追加标题? (寻找与@ QueryMap / @ FieldMap类似的东西,但是对于标题)
注意:我在初始化客户端时没有标题列表(因此不能使用Interceptor来执行此操作)。
答案 0 :(得分:2)
你仍然可以(并且必须)使用拦截器 您只需要一点建筑。
首先创建一个提供必要标题的帮助程序。
public class AnalyticsHeader {
private String analyticsHeaderName;
private String analyticsHeaderValue;
public void setHeaderValue(String header) {
this.analyticsHeaderValue = header;
}
public void setHeaderName(String header) {
this.analyticsHeaderName = header;
}
public String getHeaderName() {
return analyticsHeaderName;
}
public String getHeaderValue() {
return analyticsHeaderValue;
}
}
将此类的实例保存在应用程序内的可访问位置,例如应用程序的MainActivity(甚至更好,使用依赖注入)
现在,在创建Interceptor时,只需将AnalyticsHeader的实例传递给拦截器:
public static final class AnalyticsInterceptor implements Interceptor {
private final AnalyticsHeader header;
public AnalyticsInterceptor(AnalyticsHeader header) {
this.header = header;
}
@Override
public Response intercept(Chain chain) throws IOException {
final Request original = chain.request();
Response response;
if (header.getHeader() != null) {
Request request = original.newBuilder()
.header(header.getHeaderName(), header.getHeaderValue())
.method(original.method(), original.body())
.build();
response = chain.proceed(request);
} else {
response = chain.proceed(original);
}
return response;
}
}
然后......
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new AnalyticsInterceptor(CentralPlaceInApp.getAnalyticsHeader());
...
retrofit = new Retrofit.Builder()
.baseUrl(config.getRestUrl())
.client(builder.build())
.build();
现在,您可以使用CentralPlaceInApp.getAnalyticsHeader().setHeaderValue(CurrentActivity.class.getSimpleName());