【问题标题】:Can't get Retrofit 2 to send globally-set headers with Dagger 2无法让 Retrofit 2 使用 Dagger 2 发送全局设置的标头
【发布时间】:2017-03-30 11:11:27
【问题描述】:

我一直想将 Dagger 2 与 Retrofit 2 结合使用。除了GET 请求之外,一切似乎都运行良好;他们似乎没有附加任何标题。

下面是我的NetworkModule,它为整个应用程序提供了所有与网络相关的依赖项(注意@ForApplication 范围注释散布在那里):

@Module
public class NetworkModule {

    // …

    @ForApplication
    @Provides
    OkHttpClient provideOkHttp(
            HttpLoggingInterceptor loggingInterceptor,
            @Named(PREFERENCE_CUR_LOGIN_SESSION) Preference<LoginSession> loginSessionPreference,
            DeviceCredentials deviceCredentials
    ) {
        final OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.addNetworkInterceptor(chain -> {
            if (loginSessionPreference.isSet()) {
                return chain.proceed(
                        chain.request().newBuilder()
                                .addHeader("token", loginSessionPreference.get().getTokenId())
                                .addHeader("device-id", deviceCredentials.getDeviceId())
                                .addHeader("Content-Type", "application/json")
                                .build()
                );
            } else {
                return chain.proceed(
                        chain.request().newBuilder().build()
                );
            }
        });
        return builder.build();
    }

    @ForApplication
    @Provides
    Retrofit provideRetrofit(Gson gson, OkHttpClient client) {
        return new Retrofit.Builder()
                .baseUrl("http://xxx.xxx.xxx/api/1.0/")
                .client(client)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }

    @ForApplication
    @Provides
    XxxApi provideApi(Retrofit retrofit) {
        return retrofit.create(XxxApi.class);
    }
}

这个模块是作为我的ApplicationComponent(以及其他模块)的依赖项提供的:

@ForApplication
@Component(
        modules = {
                ApplicationModule.class,
                RuntimeModule.class,
                DateFormatModule.class,
                PreferenceModule.class,
                NetworkModule.class
        }
)
public interface ApplicationComponent {

    // …
}

我已经运行了一个调试会话并确认loginSessionPreference.isSet() 被评估为true,但我的请求仍然显示没有任何标题:

11-16 16:55:22.748 21747-22569/xxx.xxx.xxx D/OkHttp: --> GET http://xxx.xxx.xxx/api/1.0/public/get-all-data/site http/1.1
11-16 16:55:22.748 21747-22569/xxx.xxx.xxx D/OkHttp: --> END GET

我错过了什么吗?

【问题讨论】:

标签: android retrofit2 dagger-2 okhttp3


【解决方案1】:

使用 .addInterceptor 代替 .addNetworkInterceptor()

【讨论】:

    【解决方案2】:

    首先像 Alex Shutov 建议的那样使用 addInterceptor()。

    其次,确保在调试模式下调用方法 addHeader()。 如果您使用相同的 Retrofit 实例(相同的注入),则无法使用它,因为 loginSessionPreference.isSet() 总是返回 false。

    您的方法 provideOkHttp() 被调用,而 OkHttpClient 是提供 Retrofit 实例所必需的。方法 provideOkHttp() 需要 Preference 并在创建对象 OkHttpClient 时注入。您可以将其视为最终变量(我认为编译器甚至使它成为最终变量)。

    请删除 loginSessionPreference 逻辑并硬编码一些标题 - 它会告诉我们是否是问题。

    在我看来,你需要稍微改变一下这个架构。

    【讨论】:

      猜你喜欢
      • 2018-04-17
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 2018-01-02
      相关资源
      最近更新 更多