首先,我想说的是,我是Android和Kotlin的新手,所以请耐心等待。一旦我说了这一点,我发现一些帖子与空的改型响应有关,这种响应可能是由错误的数据类引起的,通常是与真实的JSON中的变量名不同的变量名(通常,这个问题可以使用@SerializedName注解来修复)。
我使用其他端点连接到我的服务器,Android应用程序总是能正确地获得响应(例如,使用只有id字段的JSON的简单响应)。所有端点都已经使用Postman进行了验证,我的一个朋友在他的iOS应用程序中使用了相同的API,对他来说效果很好。
如何示例化改造:
请求制作器.kt
interface ApiService {
@Headers("Content-Type: application/json")
@POST("getUserToken/")
suspend fun getUserToken(@Body userData: getUserTokenRequestData): Response<getUserTokenResponse>
@Headers("Content-Type: application/json")
@POST("registerNewUserWithTables/")
suspend fun signupNewUser(@Body userData: singupUserTokenRequestData): Response<singupUserTokenResponse>
@Headers("Content-Type: application/json")
@POST("getProductsByUserId/")
suspend fun getUserProductsById(@Body userData: getUserProductsByIdRequestData): Response<getUserProductsByIdResponse>
}
class RequestsMaker {
// Receive the context of the activity to pr
lateinit var data: String
object ApiClient {
private const val BASE_URL: String = "http://myserver.com/"
private val gson : Gson by lazy {
GsonBuilder().setLenient().create()
}
private val httpClient : OkHttpClient by lazy {
OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build()
}
private val retrofit : Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
val apiService : ApiService by lazy{
retrofit.create(ApiService::class.java)
}
}
fun getRequestService():ApiService{
return ApiClient.apiService
}
}
定义的数据类(我手动创建,但由于失败,我还使用了“Kotlindata class File from JSON”Android Studio插件:
data class getUserProductsByIdRequestData(val id: Int)
data class getUserProductsByIdResponse(val products: productDataClass)
data class productDataClass(
val locations: List<Location>
)
data class Location(
val id: Int,
val storageAreas: List<StorageArea>
)
data class StorageArea(
val id: Int,
val products: List<Product>
)
data class Product(
val expirationDate: String,
val id: Int,
val name: String,
val purchaseDate: String
)
来自服务器的预期JSON响应如下所示(通过使用Postman获得):
POST请求
http://myserver.com/getProductsByUserId/
{
"id": 1
}
回应
{
"locations": [
{
"id": 2,
"storageAreas": [
{
"id": 2,
"products": [
{
"id": 4,
"name": "Ipad Goloso",
"purchaseDate": "2021-06-01",
"expirationDate": "2021-05-25"
}
]
}
]
}
]
}
我使用一个协程来调用它,我是这样使用它的:
private fun executeCall() {
var retrofit = RequestsMaker().getRequestService()
var request = getUserProductsByIdRequestData(id = 2)
GlobalScope.launch(Dispatchers.Main) {
try {
var response = retrofit.getUserProductsById(request)
if (response.isSuccessful && response.body() != null) {
val content = response.body()
if (content != null) {
Log.v("It worked message RESULT: ", content.toString())
}
}
else {
Log.w("Something went wrong with the request","lol")
//Toast.makeText(context, "Something went wrong with the request", Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
// This is the point to indicate the server is not responding
Log.e("ExceptionError message", e.message.toString())
Log.e("ExceptionError cause", e.cause.toString())
Log.e("ExceptionError localizedMessage", e.localizedMessage.toString())
Toast.makeText(applicationContext, "ERROR in the connection to the server", Toast.LENGTH_LONG).show()
}
}
}
但结果是检索到的产品始终为空... x1c 0d1x
任何想法都将是非常受欢迎的,因为我没有找到任何有用的信息,我如何可以解决这个问题后,一些天。
顺祝商祺。
1条答案
按热度按时间zwghvu4y1#
你的改进函数返回一个getUserProductsByIdResponse。这个类在它的构造函数中需要一个瓦尔products。它没有得到--响应的顶层是一个名为“location”的数组。所以product字段(响应中唯一的字段)将被设置为null,其余的数据将被丢弃。
换句话说,响应数据结构与实际返回的数据不匹配。结果多了一层。可能是因为您为返回多个产品的单独请求编写了它,而这个请求只返回单个产品。