Retrofit 2.0 删除、放置不起作用
Retrofit 2.0 delete, put are not working
我正在尝试用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".
有人可以帮我理解为什么会这样吗?非常感谢。
更新一:增加调试信息截图。
您将在响应中看到,检查请求信息,方法是 "GET",但标记显示方法 = "DELETE"。
更新2:根据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: <-- 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.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",
"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
@DELETE("books/{id}")
Call<Void> deleteBook(@Path("id") int bookId);
这是不正确的。
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.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",
"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)
我自己找到答案。这是一个愚蠢的错误......当我调试我的响应消息时,我发现在我的删除和放置方法中,reponse--> rawResponse--> priorResponse: Response{protocol=http/1 .1,代码=301,消息=永久移动,url=http://www.example.com/56eb7034cada930009ab0998/clean}
在我的正确获取函数中,priorResponse 为空。我在那里阅读 HTTP basic 信息,发现
If a client issues a GET request to "/testdir/" (i.e., 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.
在我的 DELETE、PUT 界面中添加此“/”作为结尾后 url,现在所有功能都可以使用了!!!有趣的是,在 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();
我正在尝试用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".
有人可以帮我理解为什么会这样吗?非常感谢。
更新一:增加调试信息截图。
您将在响应中看到,检查请求信息,方法是 "GET",但标记显示方法 = "DELETE"。
更新2:根据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: <-- 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.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", "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
@DELETE("books/{id}") Call<Void> deleteBook(@Path("id") int bookId);
这是不正确的。
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.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", "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)
我自己找到答案。这是一个愚蠢的错误......当我调试我的响应消息时,我发现在我的删除和放置方法中,reponse--> rawResponse--> priorResponse: Response{protocol=http/1 .1,代码=301,消息=永久移动,url=http://www.example.com/56eb7034cada930009ab0998/clean}
在我的正确获取函数中,priorResponse 为空。我在那里阅读 HTTP basic 信息,发现
If a client issues a GET request to "/testdir/" (i.e., 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.
在我的 DELETE、PUT 界面中添加此“/”作为结尾后 url,现在所有功能都可以使用了!!!有趣的是,在 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();