如何使用 Retrofit @Query 调用 REST API

Posted

技术标签:

【中文标题】如何使用 Retrofit @Query 调用 REST API【英文标题】:How to call REST API with Retrofit @Query 【发布时间】:2019-03-17 05:50:22 【问题描述】:

我无法获取 idCafe 的数据库。

这是来自网络服务的网址:

https://admin-services-dot-annular-bucksaw-167705.appspot.com/_ah/api/meja?idCafe=123445

API 服务接口:

@GET ("meja?idCafe")
fun getTable(@Query("idCafe") idCafe: String): Call<List<Table>>

我用这个函数调用api:

private fun getTableList(idCafe:String)
    val apiService : Service = Client.getClient()!!.create(Service::class.java)
    apiService.getTable(idCafe).enqueue(object : Callback<List<Table>>

        override fun onResponse(call: Call<List<Table>>?, response: Response<List<Table>>?) 

            Log.i("IdMeja", "id : " + response?.body())
            if (response != null && response.isSuccessful) 
                val listTable = response.body()
                if (listTable == null || listTable.isEmpty()) 
                    Toast.makeText(this@MainActivity, "Tidak ada meja", Toast.LENGTH_SHORT).show()
                
                else
                    tableList = ArrayList(listTable)
                    // update list table
                    dataAdapter.updateData(tableList)
                
            
            else
                Log.i("idCafe", " $idCafe")
                Toast.makeText(this@MainActivity, "Gagal dapat meja", Toast.LENGTH_SHORT).show()

            
        

        override fun onFailure(call: Call<List<Table>>?, t: Throwable?) 

            Log.i("fail",t.toString() )
            Toast.makeText(this@MainActivity, "Gagal", Toast.LENGTH_SHORT).show()
        
    )

但是响应不成功。我可以获取 idCafe,但无法获取 Table 的数据。 请帮我解决这个问题。

【问题讨论】:

如果你能显示错误日志会很有用 发布原始端点即真正的 url...并发布日志错误 【参考方案1】:

这样使用

@GET ("meja")
fun getTable(@Query("idCafe") idCafe: Int): Call<List<Table>>

您不必在 URL 中包含 ?查询变量

【讨论】:

它会返回类似“java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT”的错误。 显示响应json?您将从该网址获得。 这里你的签名得到&lt;List&lt;Table&gt;&gt; 这是数组但实际结果来自对象。应为 BEGIN_ARRAY 但为 BEGIN_OBJECT 错误意味着 这是响应 json "daf​​tarMeja": [ "nama": "1", "tersedia": true, "id": "5648554290839552" , "nama": "2", "tersedia" :真,“id”:“5769015641243648”,“nama”:“3”,“tersedia”:真,“id”:“5687539843203072”,【参考方案2】:

当您使用@Query 时,Retrofit 将为您构建查询参数。无需在 URL 中指定。

这意味着你应该像这样声明接口:

@GET ("meja")
fun getTable(@Query("idCafe") idCafe: String): Call<List<Table>>

Retrofit 然后将使用注释中的名称 - idCafe - 并使用它构建参数。

你可以继续使用字符串,因为改造可以很容易地处理它。但是,如果 idCafe 在您的应用程序中更好地建模为整数,那么我建议您改用 Int

@GET ("meja")
fun getTable(@Query("idCafe") idCafe: Int): Call<List<Table>>

请注意,这只是可能的,因为在 URL 中 idCafe 是一个整数。

【讨论】:

【参考方案3】:

像这样调用你的 api

@GET ("meja")
fun getTable(@Query("idCafe") idCafe: String): Call<TableResponse>

而表响应调用如下-

class TableResponse 
     @SerializedName("daftarMeja")
     List<Table> list;

     public List<Table> getList() 
          return list;
     

     public void setList(List<Table> list) 
          this.list = list;
     

您不能在 api 调用中使用 Call&lt;List&lt;Table&gt;&gt; 作为结果,因为错误显示“BEGIN_ARRAY but was BEGIN_OBJECT”

【讨论】:

以上是关于如何使用 Retrofit @Query 调用 REST API的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Retrofit 2 + OkHttp 3 加密/隐藏 HTTPS 调用的主体?

【Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...

Retrofit 使用 DELETE 方式

Retrofit 动态参数(非固定参数 非必须参数)(Get Post请求)

如何使用 Retrofit 在 android 中调用图像上传 Web 服务 (ASP.NET) .asmx 文件

使用 Retrofit2(kotlin) 的 CURL 请求