无法在 Body raw 上使用 Retrofit 发布

Posted

技术标签:

【中文标题】无法在 Body raw 上使用 Retrofit 发布【英文标题】:Can't POST using Retrofit on Body raw 【发布时间】:2021-08-18 21:55:42 【问题描述】:

我想使用 body raw 在 API 上发布数据,但 response.body 上总是为 null 并且数据未发送。

这是我的改装课:

public class ApiClient 
public static Retrofit retrofit;
private static final String BASE_URL = BuildConfig.BASE_URL;

public static Retrofit getRetrofitInstance()
    if (retrofit == null)
        retrofit =  new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    

    return  retrofit;

然后是界面:

public interface SendData 
@POST("/")
Call<DataItem> sendData(@Body DataItem body);

有类模型:

public class DataItem
private String date;
private String imgUrl;
private double probability;
private String latitude;
private String longtitude;
private String className;

public DataItem(String date, String imgUrl, double probability, String latitude, String longtitude, String className) 
    this.date = date;
    this.imgUrl = imgUrl;
    this.probability = probability;
    this.latitude = latitude;
    this.longtitude = longtitude;
    this.className = className;


public String getDate()
    return date;


public String getImgUrl()
    return imgUrl;


public double getProbability()
    return probability;


public String getLatitude()
    return latitude;


public String getLongtitude()
    return longtitude;


public String getClassName()
    return className;

这里调用改造来发布数据:

DataItem data = new DataItem(currentDate, imgUrl, probability, latitude, longitude, class_name);

                    SendData service = ApiClient.getRetrofitInstance().create(SendData.class);
                    Call<DataItem> call = service.sendData(data);
                    call.enqueue(new Callback<DataItem>() 
                        @Override
                        public void onResponse(Call<DataItem> call, Response<DataItem> response) 
                            String result = String.valueOf(response.body());
                            Log.d("MainActivity", "response = " + response.message());
                            Log.d("MainActivity", "result = " + result);
                            timingSendData();
                            Toast.makeText(MainActivity.this, "Data Send!", Toast.LENGTH_SHORT).show();
                        

                        @Override
                        public void onFailure(Call<DataItem> call, Throwable t) 
                            Log.d(TAG, "onFailure: "+t.getMessage());
                            Log.d(TAG, "onFailure: "+t.getLocalizedMessage());
                            Toast.makeText(MainActivity.this, "Cannot Send Data!", Toast.LENGTH_SHORT).show();
                        
                    );

我已经在模型中使用了 serilaizaton,我也使用了 hashmap 但仍然无法发布数据。 API 也在 postman 中测试过并且可以正常工作

编辑:遵循@DinkarKumar 的建议后,将数据发布到 API 即可。但这让我感到困惑的是,响应不是在方法 onResponse() 上而是在方法 onFailure() 上,至少数据可以发布到 API。 PS:我移动了API的URL

【问题讨论】:

你得到什么错误代码? @DinkarKumar 没有错误,没有消息但 API 中没有添加数据 它的 200 ok 状态? @DinkarKumar 不,不是,我已经检查过了。状态码 = 500 【参考方案1】:

您应该将className 更改为class_name,因为这是真正的字段名称,或者如果您想坚持使用className,那么您应该注释class_name。 如下所示,该示例使用 GSON 库语法。

@SerializedName("class_name")
public String className;

当我使用 Postman 进行测试时,您的回复也不是 DataItem,而是一个字符串 Image Added

所以我认为你也应该改变

Call<DataItem> sendData(@Body DataItem body);

Call<String> sendData(@Body DataItem body);

【讨论】:

感谢您的回答,但遗憾的是还是一样。状态码还是 500 您能否在我要求您更改时发布更新的代码,以便我查看是否一切正常。 不要将其作为答案发布。 如果您使用 GSON SerializedName 注释,您需要将所有变量公开 还是不行,先生。我只将 className 更改为 class_name 也不起作用【参考方案2】:

除了@DinkarKumar 推荐的更改之外,您还应该有这个Content-Type 标头

@Headers("Content-Type: application/json")
@POST("/")
Call<String> sendData(@Body DataItem body);

API also tested in postman and it's worked - 在 Postman 中,如果您删除 content-type 标头,您将获得 HTTP 400 和


    "msg": "Missing JSON in request"

【讨论】:

【参考方案3】:

您的响应不是 json 对象而是列表。你应该改变你的界面。我认为这就是 onFailure() 触发的原因。

public interface SendData 
@POST
Call<List<DataItem>> sendData(@Body DataItem body);

或者你只需​​要用 json 对象包装该列表。

【讨论】:

哈哈哈……好糊涂。也获得了投票。 他想将数据发布到api端点。 我误解并编辑了我的答案?️

以上是关于无法在 Body raw 上使用 Retrofit 发布的主要内容,如果未能解决你的问题,请参考以下文章

Retrofit 2.0如何获得反序列化错误response.body

Retrofit 2.0如何获得反序列化错误response.body

Retrofit - @Body 参数不能与表单或多部分编码一起使用

Retrofit @body的使用

无法在HttpLoggingInterceptor Retrofit2.0上解析setLevel

Okhttp + Retrofit @Body 请求 - 传输编码:添加了分块