0

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)
Kamil
  • 85
  • 1
  • 7
  • Can you paste the response JSON which is generated? Though I see this error is something wrong on the server-side and not android. – Rajen Raiyarela Aug 14 '20 at 11:51
  • Check [this](https://stackoverflow.com/questions/39918814/use-jsonreader-setlenienttrue-to-accept-malformed-json-at-line-1-column-1-path) – Rajen Raiyarela Aug 14 '20 at 11:53
  • I'm unable to make the interceptor works. `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)` – Kamil Aug 14 '20 at 12:01
  • Pl edit your question and add this details to it, so others can check and revert – Rajen Raiyarela Aug 14 '20 at 12:02
  • Well I just made working the HttpInterceptor. I see the problem, it returns me an HTML page. This is the normal response when the auth request didn't work. Might be due to my @body ? – Kamil Aug 14 '20 at 13:08

2 Answers2

0

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)
    }
 })
}
akhilesh0707
  • 5,244
  • 4
  • 34
  • 44
KuLdip PaTel
  • 871
  • 6
  • 17
0

I found the solution.

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

Kotlin was doing a wrong parsing.

Kamil
  • 85
  • 1
  • 7