【问题标题】:Android make POST request with retrofitAndroid 通过改造发出 POST 请求
【发布时间】:2021-05-19 03:02:24
【问题描述】:

我正在尝试使用改造库发出我的第一个 POST 请求以使用户登录,但它不起作用,我不明白为什么。如果我发出 GET 请求,它可以工作,但是 POST 出现问题,我不明白为什么。 我的 API 在本地网络服务器上运行 我的 LoginService 代码:

private const val BASE_URL = "http://localhost:10000/api/"


/**
* Build the Moshi object that Retrofit will be using, making sure to add the Kotlin adapter for
* full Kotlin compatibility.
*/
private val moshi = Moshi.Builder()
   .add(KotlinJsonAdapterFactory())
   .build()



/**
* Use the Retrofit builder to build a retrofit object using a Moshi converter with our Moshi
* object.
*/
private val retrofit = Retrofit.Builder()
   .addConverterFactory(MoshiConverterFactory.create(moshi))
   .baseUrl(BASE_URL)
   .build()



interface LoginApiService {
   @Headers("Content-Type: application/json")
   @POST("login")
   suspend fun makeLogin(@Body usr: User): LoginResponse
}


/**
* A public Api object that exposes the lazy-initialized Retrofit service
*/
object LoginApi {
   val retrofitService : LoginApiService by lazy { retrofit.create(LoginApiService::class.java) }
}

LoginResponse 类的代码

data class LoginResponse(
   val token: String,
   val expiration: Date,
   val role: Int)

User 类的代码:

data class User(
    val mail: String,
    val pw: String
) : Parcelable

发出请求的 ViewModel 的代码:

private fun makeLogin(email: String, password: String) {
        viewModelScope.launch {
            try {
                val usr = User(email, password)
                val rsp = LoginApi.retrofitService.makeLogin(usr)         
                _isLogged.value = true
            } catch (ex: Exception) {
                _status.value = LoginStatus.ERROR
            }
        }
    } 

有人可以帮我解决这个问题吗?似乎它没有发送请求。 我的改造调用在 try-catch 块中的 logcat 中生成此错误

java.lang.IllegalArgumentException: Unable to create converter for class com.example.ticketapp.network.LoginResponse
       for method LoginApiService.makeLogin

【问题讨论】:

  • 您的 AndroidManifest.xml 文件中是否有 Internet 权限声明?
  • @VictorCold 是的,还有所有的毕业生
  • 可以尝试在User类中添加@Parcelize注解。我不确定这是否能解决问题,但 AFAIK 仅从 Parcelable 继承是不够的。
  • 但我已经有@parcelize
  • 可能是因为您的“到期”字段是日期类型。基本上,JSON 只支持原始字段。我想在您的情况下,您可以尝试将日期更改为字符串或长。取决于您如何从服务器返回它。

标签: android kotlin retrofit retrofit2


【解决方案1】:

默认 Retrofit 的超时时间是 10 秒。你可以这样修复它:

        val client = OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build()

        val retrofit  = Retrofit.Builder()
            ...
            .client(client)
            .build()

这里我设置为 30 秒,但你可以使用任何你想要的数字和时间单位。

UPD

您可以将 Retorfit 构建器存储在单独的文件中,如下所示:

interface WebService {
    companion object {

        fun <T> build(clazz: Class<T>): T {
        
            val client = OkHttpClient.Builder()
                ...
                .build()

            val retrofit  = Retrofit.Builder()
                ...
                .build()
            return retrofit.create(clazz)
        }
    }
}

那么你可以有多个 ApiService 接口。并像这样使用它们:

val myApiService = WebService.build(MyApiServiceInterface::class.java)
myApiService.myRequestFunction()

【讨论】:

  • 谢谢。现在我在同一个文件中拥有改造构建器、API 和服务。您知道如何使用改造构建器仅制作一个文件并由每个服务调用吗?因为我会做很多服务
  • 由于某种原因,今天它不起作用...我得到java.net.ConnectException: Failed to connect to localhost/127.0.0.1:10000,我没有改变昨天的任何东西
【解决方案2】:

尝试添加

android:usesCleartextTraffic="true"

进入清单中的应用程序标签

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 2013-02-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2018-04-25
    • 1970-01-01
    相关资源
    最近更新 更多