Как я могу отправить запрос с помощью Retrofit? - PullRequest
3 голосов
/ 04 апреля 2019

Я пытаюсь отправить пост-запрос с помощью Retrofit, но сервер отвечает ошибкой 400: Неверный запрос.

BaseURL: http://taskdemoserver.pythonanywhere.com

Это скриншот серверной документации.

Server doc

Это интерфейс для модернизации.

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

Я создаю экземпляр Retrofit в своем хранилище.

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)

...

}

Это ошибка, которую я получаю, когда пытаюсь опубликовать задание.

Error 400: Bad Request

Ответы [ 3 ]

1 голос
/ 04 апреля 2019

Базовые URL всегда должны заканчиваться на /

Изменить .baseUrl("http://taskdemoserver.pythonanywhere.com") на

val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl("http://taskdemoserver.pythonanywhere.com")
        .addConverterFactory(GsonConverterFactory.create(gson))
        .client(httpClient)
        .build()

на .baseUrl("http://taskdemoserver.pythonanywhere.com/")

0 голосов
/ 04 апреля 2019

Несмотря на то, что я не уверен на 100%, если это ваша проблема, поскольку загруженная вами документация по серверу неполная, я уверен, что проблема в том, что сервер просит вас отправить данные задачибыть созданным с использованием MIME-типа application/x-www-form-urlencoded, поэтому он говорит formdata справа от конечной точки Создать задачу на изображении, которое вы загрузили вместе с документацией сервера.

Однако вы используете @Body tasks: TaskListContainer, который вместо этого отправляет информацию о новой задаче в виде данных JSON application/json. (@ аннотация тела)

Это то, что вы делаете

Я проверил вашу конечную точку с помощью Почтальон , используя application/json в качестве Content-Typeвашего запроса.Именно этим занимается сейчас Retrofit, поскольку вы использовали аннотацию @Body в сервисе Retrofit.

Headers wrong Response wrong

Это то, что вы должны сделать вместо этого

Теперь, если я отправлю запрос POST с почтальоном, но с использованием типа form-data, с полем с ключом task и значением String, представляющим имязадача, которая будет создана, я получаю успешный ответ.

Headers correct Response correct

Чтобы сообщить Retrofit отправить запрос POST, какдля этого вы должны определить свой метод saveTask следующим образом:

    interface Service {
    ...

    @Headers("user: joan")
    @FormUrlEncoded
    @POST("task")
    fun saveTask (@Field("task") taskname: String) : Call<Task>

    ...
}

Более подробную информацию о @FormUrlEncoded аннотации вы можете найти в официальной документации .

Также, как сказал @YuriPopiv, вам не хватает последней косой черты в вашем baseUrl.Попробуйте установить его следующим образом .baseUrl("http://taskdemoserver.pythonanywhere.com/") или определить конечную точку, начиная с ведущего /.

Начиная с документы :

Базовые URL-адреса всегда должны заканчиваться на /.Завершающий / гарантирует, что значения конечных точек, которые являются относительными путями, будут правильно добавляться к базе, имеющей компоненты пути.

0 голосов
/ 04 апреля 2019

Возможно, у вас возникли следующие проблемы:

1) Сервер не может определить содержание ответа.Попробуйте добавить заголовок с типом содержимого: @Headers("Content-Type: application/json")

2) Ваш базовый URL отсутствует / косая черта в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...