【问题标题】:Retrofit 2.0 delete, put are not workingRetrofit 2.0 删除、放置不工作
【发布时间】:2016-07-15 07:51:55
【问题描述】:

我正在尝试使用 Retrofit 2.0 来实现一个库系统。 可以添加图书、列出所有图书信息、列出一本书信息、删除一本书、删除所有图书、更新一本书信息。

我的 baseURL 末尾有一个“/”:

http://www.example.com/webservice/

前三个功能运行良好:

@GET("books")
Call<ArrayList<Book>> listBooks();

@POST("books")
Call<Book> addBook(@Body Book book);

@GET("books/{id}")
Call<Book> getBookInfo(@Path("id") int bookId);

但是,这三个根本不起作用:

@DELETE("books/{id}")
Call<Void> deleteBook(@Path("id") int bookId);

@PUT("books/{id}")
Call<Book> updateBook(@Path("id") int bookId , @Body Book book);

@DELETE("clean")
Call<Void> deleteAll();

例如,这是我的 deleteBook 功能:

        Gson gson = new GsonBuilder()
        .setDateFormat(Constant.DATE_FORMAT)
        .create();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(Constant.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build();

LibraryService libraryServiceAPI = retrofit.create(LibraryService.class);
Call<Void> deleteBookCall = libraryServiceAPI.deleteBook(bookId);
deleteBookCall.enqueue(new Callback<Void>() {
    @Override
    public void onResponse(Call<Void> call, Response<Void> response) {
        if (response.isSuccessful()) {
            if (response.code() == 204) { // I get 200 here, not 204
                // but this is what I find:
                // response-->rawResponse-->request-->method == "GET"
                // This should be DELETE, am I right?
            }
        } else {
            Log.d(DELETE_BOOK_ERROR, String.valueOf(response.code()));
        }
    }

    @Override
    public void onFailure(Call<Void> call, Throwable t) {
        Log.d(DELETE_BOOK_ERROR, RESPONSE_FAILURE);
    }
});

当我调试数据时:我发现 response-->rawResponse-->request-->method == "GET",在这个例子中应该是 "DELETE"。在我实现 updateBook 和 deleteAll 功能后,我发现它们有同样的问题,这里的方法都等于“GET”而不是“PUT”和“DELETE”。

有人能帮我理解为什么会这样吗?非常感谢。

更新1:添加调试信息截图。

你会在响应中看到,检查请求信息,方法是“GET”,但是标签显示方法=“DELETE”。

Update2:根据 Dexter 的建议,我添加了 HttpLoggingInterceptor 进行调试,

            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.interceptors().add(logging);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(httpClient.build()).build();

这里有两条日志:

  1. @GET("books/{id}") Call<Book> getBookInfo(@Path("id") int bookId); 这是正确的。

03-28 00:26:00.842 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: --> GET http://www.example.com/56eb7034cada930009ab0998/books/2 http/1.1 03-28 00:26:00.842 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: --> END GET 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: http://www.example.com/56eb7034cada930009ab0998/books/2/ (191ms) 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: 连接:保持活动 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: 服务器: gunicorn/18.0 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:日期:3 月 28 日星期一 2016 06:03:30 格林威治标准时间 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Type: 应用程序/json 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Length: 153 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:通过:1.1 vegur 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: OkHttp-Sent-Millis: 1459139160940 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: OkHttp-Received-Millis: 1459139161040 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: {"author": "123", “类别”:“123”,“id”:2,“lastCheckedOut”:空, “lastCheckedOutBy”:空,“发布者”:“123”,“标题”:“123”,“url”: “/books/2/”} 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:

  1. @DELETE("books/{id}") Call<Void> deleteBook(@Path("id") int bookId); 这是不正确的。

03-28 00:26:35.602 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: --> 删除http://www.example.com/56eb7034cada930009ab0998/books/2 http/1.1 03-28 00:26:35.602 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: --> END DELETE 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: http://www.example.com/56eb7034cada930009ab0998/books/2/ (481ms) 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: 连接:保持活动 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: 服务器: gunicorn/18.0 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:日期:3 月 28 日星期一 2016 06:04:05 格林威治标准时间 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Type: 应用程序/json 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Length: 153 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:通过:1.1 vegur 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: OkHttp-Sent-Millis: 1459139195900 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: OkHttp-Received-Millis: 1459139196088 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: {"author": "123", “类别”:“123”,“id”:2,“lastCheckedOut”:空, “lastCheckedOutBy”:空,“发布者”:“123”,“标题”:“123”,“url”: “/books/2/”} 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp:

【问题讨论】:

  • 你能记录下请求和响应吗?
  • @Raghunandan 我在那里更新了屏幕截图。谢谢。
  • 使用“HttpLoggingInterceptor”进行调试。它会让你清楚地知道哪里出了问题!
  • @Dexter 感谢您的建议,我将日志粘贴到此处。通过在 chrome 中使用 Advanced rest 客户端,通过调用 Delete,相同的 URL,我将得到 204 显示这本书已成功删除,但使用我的应用程序,使用改造 2.0 调用删除,我得到 200 作为响应并且这本书仍然存在,未删除。

标签: java android retrofit retrofit2


【解决方案1】:

我自己找到答案。这是一个愚蠢的错误......当我调试我的响应消息时,我发现在我的删除和放置方法中,reponse--> rawResponse--> priorResponse: Response{protocol=http/1.1, code=301 , message=永久移动, url=http://www.example.com/56eb7034cada930009ab0998/clean}

在我正确的 get 函数中,priorResponse 为空。我在那里阅读HTTP basic信息,发现

如果客户端向“/testdir/”发出 GET 请求(即,在 目录).......有趣的是,如果客户端向“/testdir”发出 GET 请求(未指定目录路径“/”),服务器会返回“301 Move Permanently”,并带有“/testdir/”的新“位置”,如下。

在我的 DELETE, PUT 接口 URL 中添加这个“/”作为结尾后,现在所有功能都可以使用了!!!有趣的是,在 chrome plugin--> Advanced Rest Client 中,我最终不需要这个“/”来使其工作。

我现在更新的界面代码为:

@GET("books")
Call<ArrayList<Book>> listBooks();

@POST("books")
Call<Book> addBook(@Body Book book);

@GET("books/{id}/")
Call<Book> getBookInfo(@Path("id") int bookId);

@DELETE("books/{id}/")
Call<Void> deleteBook(@Path("id") int bookId);

@PUT("books/{id}/")
Call<Book> updateBook(@Path("id") int bookId, @Body Book book);

@DELETE("clean/")
Call<Void> deleteAll();

【讨论】:

  • 哇,很高兴找到我的朋友。我看着这个很困惑,我现在明白了。我通常使用 @DELETE("path") find 没有问题。很高兴看到你解决了这个问题:)
  • 你好,@xiaoyaoworm 我是 android 开发新手,我也尝试过一种改造,但我无法发布工作,放置和删除方法。您能否转发您已经完成所有不同方法的任何改造项目......那将是伟大的。谢谢 。我的邮件是tapankumarpatro05@gmail.com 请兄弟..
  • @TapanKumarPatro github.com/xiaoyaoworm/Prolific-Library 给你。我还有一个问题问如何在改造时删除,看看:stackoverflow.com/questions/36251080/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多