android - 使用 Kotlin 在 Android 中使用 Body 制作 Retrofit2 POST
问题描述
我正在尝试在使用 Kotlin 的 Android 应用程序中使用 Retrofit 调用 API。API 需要类似于以下示例输入的标头和正文:
样本输入
标题:
登录名:65848614-6697-4cf7-a64a-e0b9374c4aee
身体:
客户 ID:DKOKTrykIQ987yQcLNehT8SWJRMyQLdP 秘密:6Jt1ENlDn9gxPu5f
内容类型必须作为 application/x-www-form-urlencoded 传递。
目前,我正在使用以下类:
YodleeService.kt
interface YodleeService {
@Headers(
"loginName: de5559cc-5375-4aca-8224-990343774c08_ADMIN",
"Api-Version: 1.1",
"Content-Type: application/x-www-form-urlencoded"
)
@POST("auth/token")
fun generateLoginToken(
@Body postBody: PostBody
) : Call<LoginToken>
}
AccountRetriever.kt
class AccountRetriever {
private val service: YodleeService
companion object {
const val BASE_URL = "https://sandbox.api.yodlee.com:443/ysl/"
}
init {
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(YodleeService::class.java)
}
fun login(callback: Callback<LoginToken>) {
val postBody = PostBody("TG86ljAk6lt28GYZlRTQWssaLmGpS6jV", "A2P9ZPEqB4uos1nv")
val call = service.generateLoginToken(postBody)
call.enqueue(callback)
}
}
邮筒
data class PostBody(
val clientId: String?,
val secret: String?
)
主要活动
class MainActivity : AppCompatActivity() {
private val accountRetriever = AccountRetriever()
private val loginCallback = object : Callback<LoginToken> {
override fun onFailure(call: Call<LoginToken>, t: Throwable) {
Log.e("MainActivity", "Problem calling Yodlee API {${t.message}")
}
override fun onResponse(call: Call<LoginToken>?, response: Response<LoginToken>?) {
response?.isSuccessful.let {
Log.i("MainActivity", "errorBody - Content = ${response?.raw()}")
val loginToken = LoginToken(
response?.body()?.accessToken ?: "",
response?.body()?.expiresIn ?: "",
response?.body()?.issuedAt ?: "")
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
accountsList.layoutManager = LinearLayoutManager(this)
if (isNetworkConnected()) {
accountRetriever.login(loginCallback)
} else {
AlertDialog.Builder(this).setTitle("No Internet Connection")
.setMessage("Please check your internet connection and try again")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert).show()
}
}
private fun isNetworkConnected(): Boolean {
val connectivityManager =
getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
}
当我调试我的应用程序时,我收到了[size=213 text=\n {\n "errorCode": "Y303",\n …]
. API 的文档说这个错误代码意味着缺少 clientId 或 secret。
当我通过调试器挖掘时,我看到原始调用读取为
Request {
method = POST, url = https: //sandbox.api.yodlee.com/ysl/auth/token,
tags = {
class retrofit2.Invocation =
com.example.budgettracker.api.YodleeService.generateLoginToken()[PostBody(
clientId = TG86ljAk6lt28GYZlRTQWssaLmGpS6jV, secret = A2P9ZPEqB4uos1nv)]
}
}
我无法确定 API 看不到 POST 正文内容的原因。任何帮助将不胜感激。
解决方案
推荐阅读
- rust - 如何为本地特征实现 std::ops::Add?
- xcode - 来自 Macports 的 GIMP 2.10.22 中的错误路径导致插件文件-gif.ui、脚本-fu.init 在执行期间无法找到
- javascript - 是否可以在 Express 应用程序中使用一个 npm 脚本启动 nodemon 和浏览器同步?
- c++ - 用于值检查的自定义迭代器
- android - 如何从片段中获取数据并将其传输到另一个片段?
- r - 使用 ggplot2 转换图表中线条上的颜色
- javascript - Antdesign:当您单击 React 中的模态按钮时调用一个函数
- python - 找到数字根?下面的问题正确吗?我认为它在样本输出中有一些错误
- sql - 在星期几执行
- arrays - slice1 = arr2d[0:1,0:2] 有什么作用?