Retrofit2报HTTP方法注解缺失错误,Repository模式整合求助
核心错误原因
你遇到的java.lang.IllegalArgumentException: HTTP method annotation is required报错,根源在于Kodein依赖注入配置完全错误:
- 你让Retrofit去创建
AuthenticationRepository的实例,但Retrofit只能用于生成带有@GET/@POST等HTTP注解的Service接口(也就是你的AuthenticationRetrofitService),AuthenticationRepository是业务层抽象,和Retrofit没有直接关系。 - 你的依赖链路完全没串联起来,导致
AuthenticationRetrofitApi和AuthenticationRepositoryImpl这两个中间层实现类根本没被DI容器实例化和使用。
修正后的Kodein配置
你需要按正确的依赖链来绑定实例:Retrofit → AuthenticationRetrofitService → AuthenticationRetrofitApi → AuthenticationRepositoryImpl → AuthenticationRepository,修正后的模块代码如下:
val retrofitModule = Kodein.Module("retrofitModule") { // 1. 绑定OkHttpClient bind<OkHttpClient>() with singleton { OkHttpClient.Builder() // 原代码newBuilder()是多余的,直接用Builder创建实例 // 可在此添加拦截器、超时时间等配置 .build() } // 2. 绑定Retrofit实例 bind<Retrofit>() with singleton { Retrofit.Builder() .baseUrl("https://127.0.0.1/api/") .client(instance()) .addConverterFactory(GsonConverterFactory.create()) // 重要:若要让Retrofit返回Either类型,需自定义CallAdapterFactory // 比如使用arrow-kt的适配工厂,否则Retrofit无法识别Either返回值 // .addCallAdapterFactory(EitherCallAdapterFactory.create()) .build() } // 3. 绑定Retrofit Service接口 bind<AuthenticationRetrofitService>() with singleton { instance<Retrofit>().create(AuthenticationRetrofitService::class.java) } // 4. 绑定AuthenticationApi的实现类 bind<AuthenticationApi>() with singleton { AuthenticationRetrofitApi(instance()) } // 5. 绑定AuthenticationRepository的实现类 bind<AuthenticationRepository>() with singleton { AuthenticationRepositoryImpl(instance()) } }
额外优化与注意事项
Retrofit返回Either的适配问题:
你的AuthenticationRetrofitService直接返回Either<Throwable, Monitor>,但默认Retrofit不支持这种返回类型,它仅支持Call<T>、Suspend<T>或自定义结果类型。你有两种解决方式:- 改用Retrofit支持的返回类型,比如
suspend fun doLogin(...) : Monitor,然后在AuthenticationRetrofitApi中捕获异常并手动包装成Either; - 引入第三方CallAdapter,比如Arrow-Kt的
RetrofitCallAdapterFactory,让Retrofit自动将响应包装成Either。
- 改用Retrofit支持的返回类型,比如
RepositoryImpl的冗余代码清理:
你的AuthenticationRepositoryImpl里的fold逻辑是多余的,直接返回api.doLogin(basicAuth)即可,因为api.doLogin已经返回Either类型,无需重复包装:class AuthenticationRepositoryImpl (private val api: AuthenticationApi) : AuthenticationRepository { override suspend fun doLogin(basicAuth: String) = api.doLogin(basicAuth) override suspend fun doLogout() = api.doLogout() }
验证调用链路
修正后,完整的调用链路会变成:UseCase → AuthenticationRepositoryImpl → AuthenticationRetrofitApi → AuthenticationRetrofitService → Retrofit,这样就能正常发起Retrofit请求了。
内容的提问来源于stack exchange,提问作者StuartDTO

