这是一个有点老问题,但在我自己考虑了一段时间之后,这就是我想到的。我很想听听任何想法!
按照标准,我在一个名为AuthWebservice的接口中定义了我的@POST:
interface AuthWebservice {
@POST("oauth/token")
@FormUrlEncoded
fun refreshToken(
@Field("grant_type")
grantType: GrantType,
@Field("client_id")
clientId: String,
@Field("client_secret")
clientSecret: String,
@Field("refresh_token")
refreshToken: String
): Call<AccessToken>
}
[注意:我正在使用 Dagger 进行依赖注入,但无论您在哪里实例化 Web 服务,以下逻辑都可以正常工作]
在我的网络模块中,我有以下内容来获取AuthWebservice的实例:
@Module
class NetworkModule {
...
@Provides
@Singleton
fun providesAuthWebservice(
retrofit: Retrofit
): AuthWebservice = retrofit.create(AuthWebservice::class.java)
...
}
这是我的解决方案:我还在AuthWebservice中包含以下方法定义:
fun refreshToken(refreshToken: String): Call<AccessToken>
请注意,没有任何类型的批注,并且该方法返回的数据类型与包含所有参数的版本相同。这将编译,但显然,如果您尝试调用它,它将在运行时失败,类似于以下内容:
java.lang.IllegalArgumentException:HTTP方法注释是必需的(例如,@GET,@POST等)。for method AuthWebservice.refreshToken
现在我创建了一个名为 的类,该类采用 .在大多数情况下,它只调用基本实例上的相应方法,除了我上面刚刚添加的方法:AuthWebserviceWrapper
AuthWebservice
class AuthWebserviceWrapper(private val base: AuthWebservice) : AuthWebservice {
// Just call the base method.
override fun refreshToken(
grantType: GrantType,
clientId: String,
clientSecret: String,
refreshToken: String
): Call<AccessToken> = base.refreshToken(
grantType,
clientId,
clientSecret,
refreshToken)
// Call the base method with defaults!
override fun refreshToken(refreshToken: String): Call<AccessToken> =
base.refreshToken(
GrantType.REFRESH_TOKEN, // Default value
BuildConfig.MY_CLIENT_ID, // Default value
BuildConfig.MY_CLIENT_SECRET, // Default value
refreshToken
)
}
最后,回到 ,我包装了 Retrofit 的默认实现,如下所示:NetworkModule
@Module
class NetworkModule {
...
@Provides
@Singleton
fun providesAuthWebservice(
retrofit: Retrofit
): AuthWebservice = AuthWebserviceWrapper(retrofit.create(AuthWebservice::class.java))
...
}
现在,当我调用时,我得到具有默认值的方法:refreshToken
class MyClass @Inject constructor(authWebservice: AuthWebservice) {
fun doSomething(refreshToken: String) {
val call = authWebservice.refreshToken(refreshToken)
}
}
这当然引入了一些样板,我不是其中的粉丝,但我认为最终它是进行Web服务调用的最干净的方式,而无需引入或的需求。@Body
@FieldMap
无论如何,这就是我的故事,我坚持下去。