【问题标题】:Retrofit Kotlin unable to create a working post request改造 Kotlin 无法创建工作帖子请求
【发布时间】:2020-08-14 11:26:04
【问题描述】:

我正在尝试使用 Retrofit 发出 POST 请求,但我无法使其工作。它确实适用于邮递员。我指定了标题“Content-Type: application/json”并在正文中设置了我的“email”和“password”参数,效果很好。

但它不适用于 Android。这是我的代码:

private fun login() {
    val user = User("test@gmail.com", "dsea2EcFI32\\\"af'xn")

    this.service.login(user).enqueue(object : Callback<LoginResponse> {
        override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
            if (response.code() == 200) {
                // TODO
            }
        }
        override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
            // TODO
            println(t.message)
        }
    })
}

请求:

    @Headers("Content-Type: application/json")
    @POST("/api/authentication/login")
    fun login(@Body body: User): Call<LoginResponse>

用户模型

data class User(val email: String, val password: String)

登录响应:

class LoginResponse {
   @SerializedName("user")
   val user : UserResponse? = null
}

class UserResponse {
   @SerializedName("id") val still : String = null
   @SerializedName("firstName") val running : String = null
   @SerializedName("lastName") val bicycle : String = null
   @SerializedName("email") val walking : String = null
   @SerializedName("token") val vehicle : String = null
}

如果身份验证失败,服务器会向我发回一个 HTML 页面,所以我遇到的唯一错误是

Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $

我已经将它设置为 true,它一直告诉我 GSON 解析的对象不是 JSON 对象,但我知道这里有一个 Android 代码

谁能帮我找到它?

PS:我什至尝试将正文作为 JSON 对象发送,但同样的错误

PS2:即使我添加了足够的退格符来接受特殊字符,这可能是由于密码造成的吗?真正的字符串是 dsea2EcFI32"af'xn

编辑:

如被问及,这是我的 HTTPInterceptor 改造构建器

    val client = OkHttpClient()
    val interceptor = HttpLoggingInterceptor()
    interceptor.level = HttpLoggingInterceptor.Level.BODY
    client.interceptors().add(interceptor)

    val retrofit = Retrofit.Builder()
        .baseUrl(BuildConfig.API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build()

    this.service = retrofit.create(LoginResponse::class.java)

【问题讨论】:

  • 你能粘贴生成的响应JSON吗?虽然我看到这个错误是服务器端的问题,而不是android。
  • 检查this
  • 我无法使拦截器工作。 val client = OkHttpClient() val interceptor = HttpLoggingInterceptor() interceptor.level = HttpLoggingInterceptor.Level.BODY client.interceptors().add(interceptor) val retrofit = Retrofit.Builder() .baseUrl(BuildConfig.API_URL) .addConverterFactory(GsonConverterFactory.create()) .client(client) .build() this.service = retrofit.create(LoginRequest::class.java)
  • 请编辑您的问题并将此详细信息添加到其中,以便其他人可以检查和恢复
  • 好吧,我刚刚开始使用 HttpInterceptor。我看到了问题,它返回给我一个 HTML 页面。这是身份验证请求不起作用时的正常响应。可能是因为我的@body ?

标签: android kotlin


【解决方案1】:

我找到了解决办法。

问题在于密码,因为其中包含反斜杠和引号。

Kotlin 进行了错误的解析。

【讨论】:

    【解决方案2】:

    像下面这样转换你的fun login对象。

        @Headers("Content-Type: application/json")
        @POST("/api/authentication/login")
        fun login(@Body requestBody: RequestBody): Call<LoginResponse>
    

    然后像这样创建一个fun

           fun makeGSONRequestBody(jsonObject: Any?): RequestBody {
            return RequestBody.create(MediaType.parse("multipart/form-data"), Gson().toJson(jsonObject))
        }
    

    您需要传递您的 User 对象,如下所示

    private fun login() {
    val user = User("test@gmail.com", "dsea2EcFI32\\\"af'xn")
    
    this.service.login(makeGSONRequestBody(user)).enqueue(object : Callback<LoginResponse> {
        override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
            if (response.code() == 200) {
                // TODO
            }
        }
        override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
            // TODO
            println(t.message)
        }
     })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-24
      • 2019-05-20
      • 1970-01-01
      • 2021-11-07
      • 2021-05-21
      相关资源
      最近更新 更多