简体   繁体   中英

Retrofit Kotlin unable to create a working post request

I'm trying to do a POST request using Retrofit but I'm unable to make it work. It does work on Postman. I specified the header "Content-Type: application/json" and set my "email" and "password" parameters in the body and it works well.

But it doesn't on Android. Here are my codes:

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)
        }
    })
}

The request:

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

User model

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

LoginResponse:

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
}

In case the auth is a failure, the server sends me back an HTML page so the only error I have is

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

I already set it to true and it keeps saying me that the GSON parsed object isn't a JSON object but I know there's an Android code here

Can someone helps me finding it?

PS: I even tried to send the body as a JSON object but same error

PS2: might this be due to the password even If I added enough backspace to accept the special characters? the real string is dsea2EcFI32"af'xn

EDIT:

As asked, here is my retrofit builder with the 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)

Convert your fun login object like below one.

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

then create a fun like this

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

you need to pass your User object like below

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)
    }
 })
}

I found the solution.

The issue was the password because it had backslashes and quotes inside of it.

Kotlin was doing a wrong parsing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM