Kotlin:Request.Builder().url json URL 连接后出错
Kotlin: Request.Builder().url json error after URL concatenation
我有一个从 api 端点获取数据的 kotlin 函数。基本 api 端点位于 activity 内的常量中。看起来像这样:
object AppConstants {
const val API_URL = "http://192.168.100.2:8000/api/"
}
函数是这样的:
private fun thisGenreBookListJson(recyclerView: RecyclerView) {
val categoryId: String = intent.getStringExtra(CATEGORY_ID).toString()
// we get the url to list all the book genres
val genreAPiUrl = AppConstants.API_URL +"books/category/$categoryId"
val thisRequest = Request.Builder().url(genreAPiUrl).build()
val client = OkHttpClient()
// enqueue makes sure the thread runs in the background
client.newCall(thisRequest).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val thisBody = response.body?.string()
val thisGson = GsonBuilder().create()
val bookList = thisGson.fromJson(thisBody, BookList::class.java)
this@CategoryViewerActivity.runOnUiThread {
recyclerView.adapter = CategoryBookListAdapter(bookList)
}
}
override fun onFailure(call: Call, e: IOException) {
println("Failed fetching URL $e")
}
})
查看 val genreAPiUrl = "http://192.168.100.2:8000/api/books/category/$categoryId"
行,如果保持原样,它会抛出 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
错误。但是,在调试应用程序时,URL 似乎形成正确。如果我将此行中的 $categoryId
替换为数据库中的类别,则代码运行时不会出现任何错误,并且在调试时,它与串联的代码相同。在函数的第一行,删除 toString()
也没有效果。
我在这里似乎找不到任何与此类似的问题。
我可能遗漏了什么?这是串联问题吗?谢谢。
你可以试试这个方法:
val genreAPiUrl = "${AppConstants.API_URL}books/category/$categoryId"
Expected BEGIN_OBJECT but was STRING at line 1 column 1
意思是说你的JSON可能格式不正确
Gson 期望您的 JSON 字符串以对象开头
{
但响应从
开始
"
IllegalStateException
被抛出是因为服务器 returns 一个错误而不是预期的 Json (我假设一些 404/40x)。
由于使用有效的 categoryId
有效,从 Intent
检索到的 categoryId
一定是无效的。
However, on debugging the app, the URL seems to be formed correctly
这可能有两种含义:
- 当使用调试器逐步执行时,您可以验证
categoryId
是一个 valid/correct id,db 中存在图书类别
- 在使用调试器单步执行时,您可以验证 URL 是否格式正确,但您没有验证
categoryId
是否为 valid/correct
案例一
由于您的调试会话显示 categoryId
是正确的,因此结论是这是一个竞争条件。有些东西一定不能正确设置 Intent
参数,或者设置得太晚,这样当你单步调试调试器时它是正确的,但当 运行 没有附加调试器时它还不正确。下一步是使用一些 print 语句来检查 categoryId
应用程序 运行 在没有调试器的情况下是否正确(可能不是),然后找出在 [=13] 中设置 id 时出了什么问题=].
案例二
在这种情况下,您需要调试根本原因,那就是 Intent
中的 id 错误。如果没有看到更多代码,就不可能说出 id 的来源以及为什么它无效。
我有一个从 api 端点获取数据的 kotlin 函数。基本 api 端点位于 activity 内的常量中。看起来像这样:
object AppConstants {
const val API_URL = "http://192.168.100.2:8000/api/"
}
函数是这样的:
private fun thisGenreBookListJson(recyclerView: RecyclerView) {
val categoryId: String = intent.getStringExtra(CATEGORY_ID).toString()
// we get the url to list all the book genres
val genreAPiUrl = AppConstants.API_URL +"books/category/$categoryId"
val thisRequest = Request.Builder().url(genreAPiUrl).build()
val client = OkHttpClient()
// enqueue makes sure the thread runs in the background
client.newCall(thisRequest).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val thisBody = response.body?.string()
val thisGson = GsonBuilder().create()
val bookList = thisGson.fromJson(thisBody, BookList::class.java)
this@CategoryViewerActivity.runOnUiThread {
recyclerView.adapter = CategoryBookListAdapter(bookList)
}
}
override fun onFailure(call: Call, e: IOException) {
println("Failed fetching URL $e")
}
})
查看 val genreAPiUrl = "http://192.168.100.2:8000/api/books/category/$categoryId"
行,如果保持原样,它会抛出 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
错误。但是,在调试应用程序时,URL 似乎形成正确。如果我将此行中的 $categoryId
替换为数据库中的类别,则代码运行时不会出现任何错误,并且在调试时,它与串联的代码相同。在函数的第一行,删除 toString()
也没有效果。
我在这里似乎找不到任何与此类似的问题。
我可能遗漏了什么?这是串联问题吗?谢谢。
你可以试试这个方法:
val genreAPiUrl = "${AppConstants.API_URL}books/category/$categoryId"
Expected BEGIN_OBJECT but was STRING at line 1 column 1
意思是说你的JSON可能格式不正确
Gson 期望您的 JSON 字符串以对象开头
{
但响应从
开始"
IllegalStateException
被抛出是因为服务器 returns 一个错误而不是预期的 Json (我假设一些 404/40x)。
由于使用有效的 categoryId
有效,从 Intent
检索到的 categoryId
一定是无效的。
However, on debugging the app, the URL seems to be formed correctly
这可能有两种含义:
- 当使用调试器逐步执行时,您可以验证
categoryId
是一个 valid/correct id,db 中存在图书类别
- 在使用调试器单步执行时,您可以验证 URL 是否格式正确,但您没有验证
categoryId
是否为 valid/correct
案例一
由于您的调试会话显示 categoryId
是正确的,因此结论是这是一个竞争条件。有些东西一定不能正确设置 Intent
参数,或者设置得太晚,这样当你单步调试调试器时它是正确的,但当 运行 没有附加调试器时它还不正确。下一步是使用一些 print 语句来检查 categoryId
应用程序 运行 在没有调试器的情况下是否正确(可能不是),然后找出在 [=13] 中设置 id 时出了什么问题=].
案例二
在这种情况下,您需要调试根本原因,那就是 Intent
中的 id 错误。如果没有看到更多代码,就不可能说出 id 的来源以及为什么它无效。