【问题标题】:Retrofit 2.0 how to delete?Retrofit 2.0如何删除?
【发布时间】:2016-03-27 18:35:05
【问题描述】:

我正在使用 Retrofit 2.0,我正在我的 Android 应用程序中实现删除功能,但是我无法成功,有人可以给我建议吗?

我都试过了:

@DELETE("books/{id}") void deleteBook(@Path("id") int itemId);

@DELETE("books/{id}") void deleteBook(@Path("id") int bookId, Callback<Response> callback);

我收到错误 java.lang.IllegalArgumentException:服务方法不能返回 void。对于方法 LibraryService.deleteBook。

我也试了一下:

Response deleteBook(@Path("id") int bookId);

Call&lt;Response&gt; deleteBook(@Path("id") int bookId);

无论我使用okhttp3.Response 还是retrofit2.Response,都会报错:'*.Response' is not a valid response body type。您是说 ResponseBody 吗?

谁能给我一个成功删除的例子?我在网上搜索,但找不到足够的信息。非常感谢。

【问题讨论】:

  • DELETE 注释使用什么导入?困惑为什么请求将其解析为 GET....
  • @Lucas 现在很困惑,import retrofit2.http.DELETE; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.PUT; import retrofit2.http.Path; 因为当我实现 PUT 功能但 url 相同时,@PUT("books/{id}") Call&lt;Book&gt; updateBook(@Path("id") int bookId , @Body Book book); 我遇到了同样的问题,响应请求方法是“GET”
  • 对于下面的问题,我新建一个问题:stackoverflow.com/questions/36255825/…

标签: java android retrofit retrofit2 http-delete


【解决方案1】:

按照你上次提到的方式这样做:

Call<ResponseBody> deleteBook(@Path("id") int bookId);

确保通过 AsyncTask 或其他线程机制调用 UI 线程。不知道你以前是否用过 RxJava + Retrofit 2,但它很好。

ResponseBody 对象将返回调用的结果。它是我用于一些不返回实体对象的 REST API 请求的,我关心的只是查看响应代码。

Call<ResponseBody> deleteRequest = mService.deleteBook(123);
deleteRequest.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // use response.code, response.headers, etc.
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // handle failure
    }
});

或者,杰克沃顿建议

使用 Void,它不仅具有更好的语义,而且在空情况下(稍微)更有效,在非空情况下效率更高(当您不关心正文时)。

所以你有:

Call<Void> deleteBook(@Path("id") int bookId);

用法:

deleteRequest.enqueue(new Callback<Void>() {
    @Override
    public void onResponse(Call<Void> call, Response<Void> response) {
        // use response.code, response.headers, etc.
    }

    @Override
    public void onFailure(Call<Void> call, Throwable t) {
        // handle failure
    }
});

如果你只关心响应代码而不关心响应的正文,那就更好了

编辑 2:省略了正确的回调定义。固定:)

【讨论】:

  • 谢谢@Lucas。这行得通!!!!在看到您的答案之前,我想我尝试了 ResponseBody 但失败了。不知道我做错了哪一部分。是的,你是对的,我想我应该把它放到 AsyncTask 中,否则如果获取太多数据,它会阻塞我的 UI。 RxJava,不确定它是什么,但我会检查它。非常感谢!!!
  • 它使用响应式编程来处理网络请求,例如您正在做的 + 一些使代码更清晰的函数式编程范例。 RxJava 使 java 中的网络更容易处理复杂的任务,我自己还在学习它,但是很多公司都开始使用它并制作 swtich
  • 程序对您的建议没有问题,但我确实有另一个问题。因为我是在做delete的工作,这样调用的话,会得到response.code() = 200,书没有被删除。我尝试了Advanced Rest Cilent,当删除成功时,扩展上显示的响应代码是204。你对此有什么想法吗? RxJava 听起来很有趣,我应该看看学习它。感谢您的建议。
  • 是的,@Lucas 完全同意你的观点,Void 是有道理的,因为除了响应代码之外我什么都不关心。
  • w3.org/Protocols/rfc2616/rfc2616-sec10.html 响应代码 204 表示成功但没有实体包含在主体中(更多理由使用回调)。我提供的链接说:“服务器已完成请求,但不需要返回实体主体,并且可能希望返回更新的元信息。响应可能包括实体标头形式的新元信息或更新元信息,如果present 应该与请求的变体相关联。”。所以当你看到响应码 204 时,就说明你删除成功了。
猜你喜欢
  • 2016-07-15
  • 1970-01-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 2015-12-13
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多