如何使用Retrofit发送发帖请求?

时间:2019-04-04 14:07:23

标签: android kotlin retrofit

我正在尝试使用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 个答案:

答案 0 :(得分:1)

基本网址应始终以/

结尾

中更改.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/")

答案 1 :(得分:0)

可能存在以下问题:

1)服务器无法定义响应的内容。 尝试添加具有以下内容类型的标头:@Headers("Content-Type: application/json")

2)您的基本网址的末尾缺少/斜杠。

答案 2 :(得分:0)

即使我不是100%确定这是否是您的问题,但由于您上载的服务器文档不完整,所以我很确定问题出在服务器要求您发送任务数据要使用哑剧类型application/x-www-form-urlencoded创建,这就是为什么它在您随服务器文档一起上传的图片中的Create Task端点右侧显示formdata的原因。

但是,您使用的是@Body tasks: TaskListContainer,而是将新任务的信息作为JSON数据application/json发送。 (@Body annotation)

这就是你在做什么

我使用application/json作为您请求的内容类型,使用Postman测试了您的端点。这就是Retrofit现在正在做的事情,因为您在Retrofit服务中使用了@Body注释。

Headers wrong Response wrong

这是您应该做的

现在,如果我通过邮递员发送POST请求,但改用form-data类型,并使用键为task的字段和表示要创建的任务名称的字符串值,则得到一个成功的响应。

Headers correct Response correct

要告诉Retrofit这样发送POST请求,您必须像这样定义saveTask方法:

    interface Service {
    ...

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

    ...
}

您可以在the official documentation中查看有关@FormUrlEncoded注释的更多信息。

此外,正如@YuriPopiv所说,您在baseUrl中缺少最后一个斜杠。尝试像这样.baseUrl("http://taskdemoserver.pythonanywhere.com/")进行设置,或定义以前导/开头的端点。

来自the docs

  

基本URL应始终以/结尾。   尾部的/可以确保作为相对路径的端点值可以正确地将自身附加到具有路径成分的基础上。