我正在尝试使用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);
    }
});


当我调试数据时:找到响应-> rawResponse->请求->方法==“ GET”,在此示例中应为“ DELETE”。实现updateBook和deleteAll功能后,我发现它们具有相同的问题,这里的方法都等于“ GET”,而不是“ PUT”和“ DELETE”。

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

更新1:添加调试信息的屏幕快照。
java -  retrofit 2.0删除,放置不起作用-LMLPHP

java -  retrofit 2.0删除,放置不起作用-LMLPHP

java -  retrofit 2.0删除,放置不起作用-LMLPHP

您将在响应中看到,检查请求信息,方法为“ 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();


这是两个日志:


@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 GMT 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:内容长度:
  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收到的Millis:1459139161040 03-28 00:26:01.038
  3171-3198 / com.xiaoyaoworm.prolificlibrary D / OkHttp:{“ author”:“ 123”,
  “类别”:“ 123”,“ id”:2,“ lastCheckedOut”:null,
  “ lastCheckedOutBy”:null,“ publisher”:“ 123”,“ title”:“ 123”,“ url”:
  “ / books / 2 /”} 03-28 00:26:01.038
  3171-3198 / com.xiaoyaoworm.prolificlibrary D / OkHttp:  (153字节的正文)03-28 00:26:01.038
  3171-3171 / com.xiaoyaoworm.prolificlibrary D / book信息响应代码:
  响应状态码:200



@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:->结束删除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 GMT 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:内容长度:
  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收到的Millis:1459139196088 03-28 00:26:36.082
  3171-3198 / com.xiaoyaoworm.prolificlibrary D / OkHttp:{“ author”:“ 123”,
  “类别”:“ 123”,“ id”:2,“ lastCheckedOut”:null,
  “ lastCheckedOutBy”:null,“ publisher”:“ 123”,“ title”:“ 123”,“ url”:
  “ / books / 2 /”} 03-28 00:26:36.082
  3171-3198 / com.xiaoyaoworm.prolificlibrary D / OkHttp:  (153字节的正文)

最佳答案

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

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


  如果客户端向“ / testdir /”发出GET请求(即在
  目录).......有趣的是,如果客户端向“ / testdir”发出GET请求(未指定目录路径“ /”),则服务器将返回“ 301永久移动”。 “ / testdir /”的新“位置”,如下所示。


在我的DELETE,PUT界面网址末尾添加此“ /”后,现在所有功能都可以使用!!!有趣的是,在chrome插件-> 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();

关于java - retrofit 2.0删除,放置不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36255825/

10-11 22:26
查看更多