如何在 Kotlin 中调用这个 API?
我正在尝试调用这个API: https://dog-facts-api.herokuapp。 com/api/v1/resources/dogs?number=2
如您所见,它返回一个 Json,其中包含有关狗的随机事实, 我的问题是当我将我的baseUrl与retrofit一起放置时:
private fun getRetrofit(): Retrofit{
return Retrofit.Builder()
.baseUrl("https://dog-facts-api.herokuapp.com/api/v1/resources/dogs?number=")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
如果我像这样放置url,它就不起作用,因为它说必须以“/”结尾 但如果我添加它,它就不起作用了。
另外,我尝试这样写:
.baseUrl("https://dog-facts-api.herokuapp.com/api/v1/resources/")
并像这样进行调用:
val call = getRetrofit().create(APIService::class.java).getFactsByNumber("dogs?number=$number")
但同样,它不起作用,它会抛出错误:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1 进程:com.eltonga.dogfacts,PID:11927 com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为 BEGIN_OBJECT,但在第 1 行第 2 列路径处为 BEGIN_ARRAY $
我的接口:
interface APIService {
@GET
suspend fun getFactsByNumber(@Url url: String): Response<FactsResponse>
}
我的数据类:
data class FactsResponse(var fact: List<String>)
我调用 API 的函数:
private fun searchByNumber(number:Int){
CoroutineScope(Dispatchers.IO).launch {
val call = getRetrofit().create(APIService::class.java).getFactsByNumber("dogs?number=$number")
val the_facts = call.body()
runOnUiThread {
if(call.isSuccessful){
val factsData = the_facts?.fact ?: emptyList()
facts.clear()
facts.addAll(factsData)
adapter.notifyDataSetChanged()
}else{
Toast.makeText(binding.btnGo.context, "Error", Toast.LENGTH_SHORT).show()
}
}
}
}
我能做什么?我对 API 工作还很陌生
I'm trying to call this API:
https://dog-facts-api.herokuapp.com/api/v1/resources/dogs?number=2
As you can see, it returns a Json with random facts about dogs,
my problem is when I put my baseUrl with retrofit:
private fun getRetrofit(): Retrofit{
return Retrofit.Builder()
.baseUrl("https://dog-facts-api.herokuapp.com/api/v1/resources/dogs?number=")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
If I put the url like that, it doesn't work, because it says that must end with an "/"
But if I add it, it doesn't work.
Also, I tried to put just like:
.baseUrl("https://dog-facts-api.herokuapp.com/api/v1/resources/")
And making the call like this:
val call = getRetrofit().create(APIService::class.java).getFactsByNumber("dogs?number=$number")
But again, it didn't work, it throws an error:
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.eltonga.dogfacts, PID: 11927
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
My Interface:
interface APIService {
@GET
suspend fun getFactsByNumber(@Url url: String): Response<FactsResponse>
}
My data class:
data class FactsResponse(var fact: List<String>)
The function where I call the API:
private fun searchByNumber(number:Int){
CoroutineScope(Dispatchers.IO).launch {
val call = getRetrofit().create(APIService::class.java).getFactsByNumber("dogs?number=$number")
val the_facts = call.body()
runOnUiThread {
if(call.isSuccessful){
val factsData = the_facts?.fact ?: emptyList()
facts.clear()
facts.addAll(factsData)
adapter.notifyDataSetChanged()
}else{
Toast.makeText(binding.btnGo.context, "Error", Toast.LENGTH_SHORT).show()
}
}
}
}
What can I do? I'm pretty new working with API
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
预期为 BEGIN_OBJECT,但结果为 BEGIN_ARRAY
上述错误表明 API 响应的根部有一个数组/列表,并且您正尝试将响应反序列化为以下对象:不是数组/列表。
如果响应采用以下格式,这将起作用
但是由于响应采用以下格式,
您需要将返回类型用
List
包装,并且该类应该只有一个fact< /code> 字符串字段。因此函数和数据类应该定义为
另外,定义接口函数以避免每次传递它
"dogs?number=$number"
的更好方法是并将函数调用为
Expected BEGIN_OBJECT but was BEGIN_ARRAY
The above error indicates that the API response has an array/list at the root and you are trying to deserialize the response to an object that is not an array/list.
This would work if the response is in the below format
But since the response is in the below format
You need to have the return type wrapped with a
List
and the class should have only afact
String field. So the function and data class should be defined asAlso, a better way of defining the interface function to avoid passing it
"dogs?number=$number"
everytime isAnd calling the function as