Reputation: 129
I'm trying to send post request with Retrofit but server response an error 400: Bad Request.
BaseURL : http://taskdemoserver.pythonanywhere.com
This is a screenshot of server documentation.
This is the Retrofit Interface.
package com.e.databaseapp
import retrofit2.Call
import retrofit2.http.*
interface Service {
@Headers("user: joan","Content-Type: application/json")
@GET( "task" )
fun getListTask() : Call<TaskListContainer>
@Headers("user: joan","Content-Type: application/json")
@POST("task")
fun saveTask (@Body task: Task) : Call<Task>
@Headers("user: joan")
@DELETE("task")
fun deleteTask (task: String) : Call<Void>
}
I create an instance of Retrofit in my repository.
lass TaskRepository(val taskDao: TaskDao) {
val gson : Gson = GsonBuilder()
.setLenient()
.create()
val loggingInterceptor : HttpLoggingInterceptor = HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY)
val httpClient : OkHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("http://taskdemoserver.pythonanywhere.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient)
.build()
val service: Service = retrofit.create(Service::class.java)
...
}
This is the errot that I get when I try to post a task.
Upvotes: 3
Views: 1072
Reputation: 6607
Even though I am not a 100% sure if this is your problem, since the server documentation you have uploaded is not complete, I am pretty confident that the problem is that the server is asking you to send the data of the task to be created using the mime type application/x-www-form-urlencoded
, that's why it says formdata
to the right of the Create Task endopoint in the picture you uploaded with the server documentation.
However, you are using @Body tasks: TaskListContainer
, which instead is sending the information of the new task(s) as JSON data application/json
. (@Body annotation)
I tested your endpoint with Postman using application/json
as the Content-Type of your request. This is what Retrofit is doing right now because you used the @Body
annotation in the Retrofit service.
Now, if I send a POST request with Postman but using the form-data
type instead, with a Field with key task
and a String value representing the name of the task to be created, I get a a successful response.
To tell Retrofit to send the POST request like this, you have to define your saveTask
method like this:
interface Service {
...
@Headers("user: joan")
@FormUrlEncoded
@POST("task")
fun saveTask (@Field("task") taskname: String) : Call<Task>
...
}
You can see more information about @FormUrlEncoded annotation in the official documentation.
Also, as @YuriPopiv said, you are missing a final slash in your baseUrl
. Try to set it like this .baseUrl("http://taskdemoserver.pythonanywhere.com/")
or define your endpoint starting with a leading /
.
From the docs:
Base URLs should always end in /. A trailing / ensures that endpoints values which are relative paths will correctly append themselves to a base which has path components.
Upvotes: 0
Reputation: 529
Base URLs should always end in /
Change .baseUrl("http://taskdemoserver.pythonanywhere.com")
in
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("http://taskdemoserver.pythonanywhere.com")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient)
.build()
to .baseUrl("http://taskdemoserver.pythonanywhere.com/")
Upvotes: 1
Reputation: 158
Possible you have on of these problems:
1) The server can't define the content of the response.
Try to add the header with content type: @Headers("Content-Type: application/json")
2) Your base url is missing /
slash at the end.
Upvotes: 0