简体   繁体   中英

Retrofit 2.0 delete, put are not working

I am giving a try to use Retrofit 2.0 to implement a library system. Which can add book, list all book info, list one book info, delete one book, delete all books, update one book info.

My baseURL has a ' / ' in its end:

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

The first three features work very well:

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

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

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

However, those three don't work at all:

@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();

For example, this is my deleteBook feature:

        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);
    }
});

When I debug the data: I find response-->rawResponse-->request-->method == "GET", which should be "DELETE" in this example. After I implement updateBook and deleteAll features, I find they have the same problem, here the methods both equals to "GET" rather than "PUT" and "DELETE".

Can Someone help me to understand why it happens like this? Thanks a lot.

Update 1: Add screenshot of debug info. 响应实例

接口

deleteBook函数,突出显示响应实例

You will see in the response, check the request info, method is "GET", but tag shows method = "DELETE".

Update2: With suggestion from Dexter, I add the HttpLoggingInterceptor for debugging,

            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();

Here are two pieces of log:

  1. @GET("books/{id}") Call<Book> getBookInfo(@Path("id") int bookId); which is correct.

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: <-- 200 OK http://www.example.com/56eb7034cada930009ab0998/books/2/ (191ms) 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Connection: keep-alive 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Server: gunicorn/18.0 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Date: Mon, 28 Mar 2016 06:03:30 GMT 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Type: application/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: Via: 1.1 vegur 03-28 00:26:01.038 3171-3198/com.xiaoyaoworm.prolific library 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", "categories": "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: <-- END HTTP (153-byte body) 03-28 00:26:01.038 3171-3171/com.xiaoyaoworm.prolificlibrary D/book info response code: Response status code: 200

  1. @DELETE("books/{id}") Call<Void> deleteBook(@Path("id") int bookId); which is not correct.

03-28 00:26:35.602 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: --> DELETE 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: <-- 200 OK http://www.example.com/56eb7034cada930009ab0998/books/2/ (481ms) 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Connection: keep-alive 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Server: gunicorn/18.0 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Date: Mon, 28 Mar 2016 06:04:05 GMT 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.prolificlibrary D/OkHttp: Content-Type: application/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: Via: 1.1 vegur 03-28 00:26:36.082 3171-3198/com.xiaoyaoworm.pr olificlibrary 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", "categories": "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: <-- END HTTP (153-byte body)

I find the answer on my own. This is a stupid mistake.....When I debug my response message, I find in my delete and put method, reponse--> rawResponse--> priorResponse: Response{protocol=http/1.1, code=301, message=MOVED PERMANENTLY, url= http://www.example.com/56eb7034cada930009ab0998/clean }

In my correct get function, priorResponse is null. I read HTTP basic information there, finding

If a client issues a GET request to "/testdir/" (ie, at the directory).......It is interesting to take note that if a client issue a GET request to "/testdir" (without specifying the directory path "/"), the server returns a "301 Move Permanently" with a new "Location" of "/testdir/", as follows.

After adding this "/" as end in my DELETE, PUT interface url, now all the features are working!!! Interesting that in chrome plugin--> Advanced Rest Client, I don't need this "/" in the end to make it work.

My updated interface code now as:

@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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM