Android 为异步 FormUrlEncoded DELETE 调用改造抛出 IllegalArgumentException 异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22572301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Retrofit throwing IllegalArgumentException exception for asynchronous FormUrlEncoded DELETE call
提问by Rickster
I'm trying to make an asynchronous POST and DELETE which is form url encoded using Retrofit in Android 4.4
我正在尝试制作一个异步 POST 和 DELETE,它是在 Android 4.4 中使用 Retrofit 编码的表单 url
Here is my client -
这是我的客户——
@FormUrlEncoded
@POST(INetwork.API_BASE_PREFIX + "/memberships.json")
void join(@Field("id") String id, Callback<?> cb);
@FormUrlEncoded
@DELETE(INetwork.API_BASE_PREFIX + "/memberships.json")
void leave(@Field("id") String id, Callback<?> cb);
And this is the exception -
这是个例外——
java.lang.IllegalArgumentException: IRepositoryClient.leave: FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).
at retrofit.RestMethodInfo.methodError(RestMethodInfo.java:118)
at retrofit.RestMethodInfo.parseMethodAnnotations(RestMethodInfo.java:191)
at retrofit.RestMethodInfo.init(RestMethodInfo.java:128)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:329)
at retrofit.RestAdapter$RestHandler.access0(RestAdapter.java:264)
at retrofit.RestAdapter$RestHandler.obtainResponse(RestAdapter.java:315)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at retrofit.Platform$Android.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:841)
I looked through the source and it basically if the method doesn't have a body and the request is formurlencoded, this exception is thrown. Also I noticed that all example of FormUrlEncoded work fine when it is not asynchronous, i.e. I have a return type of some sort and no callback - sorry I'm a little lost
我查看了源代码,基本上如果该方法没有主体并且请求是格式编码的,则会引发此异常。我还注意到 FormUrlEncoded 的所有示例在非异步时都可以正常工作,即我有某种类型的返回类型并且没有回调 - 对不起,我有点迷茫
Should I send an empty body? Am I required to send one and won't the @Field parameters suffice?
我应该发送一个空的身体吗?我是否需要发送一个@Field 参数是否足够?
Using Retrofit 1.5.0
使用改造 1.5.0
回答by Jake Wharton
The RFC for HTTP is unclear on whether or not the DELETE method is allowed to have a request body or not. Retrofit is raising an error on the side of caution by not having one.
HTTP 的 RFC 不清楚是否允许 DELETE 方法具有请求正文。出于谨慎的考虑,Retrofit 会因为没有 Retrofit 而引发错误。
However, you can still include one (assuming the HTTP client supports it) by using a custom HTTP method annotation.
但是,您仍然可以通过使用自定义 HTTP 方法注释来包含一个(假设 HTTP 客户端支持它)。
package com.myapp;
@Target(METHOD)
@Retention(RUNTIME)
@RestMethod(value = "DELETE", hasBody = true)
public @interface BODY_DELETE {
String value();
}
Now specify your interface method using the custom annotation that you defined.
现在使用您定义的自定义注释指定您的接口方法。
@FormUrlEncoded
@BODY_DELETE(INetwork.API_BASE_PREFIX + "/memberships.json")
void leave(@Field("id") String id, Callback<?> cb);
回答by radu122
Updated answer for Retrofit 2.0:
Retrofit 2.0 的更新答案:
Retrofit 2 doesn't seem to have @RestMethod any more, so here is what works:
Retrofit 2 似乎不再有 @RestMethod,所以这里是有效的:
@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
void leave(@Field("id") String id, Callback<?> cb);
For retrofit 2.+
用于改造 2.+
@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
Callback<?> cb(@Field("id") String id);
and for RxRetrofit 2.+
和 RxRetrofit 2.+
@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
Observable<?> cb(@Field("id") String id);