为异步FormUrlEncoded DELETE调用改进抛出IllegalArgumentException异常

时间:2014-03-22 01:31:57

标签: android post http-post retrofit http-delete

我正在尝试创建一个异步POST和DELETE,这是使用Android 4.4中的Retrofit编码的url格式

这是我的客户 -

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

这是例外 -

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.access$100(RestAdapter.java:264)
        at retrofit.RestAdapter$RestHandler$2.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$2$1.run(Platform.java:142)
        at java.lang.Thread.run(Thread.java:841)

我查看了源代码,基本上如果方法没有正文并且请求是formurlencoded,则抛出此异常。另外我注意到FormUrlEncoded的所有例子在非异步时工作正常,即我有某种类型的返回类型而且没有回调 - 抱歉我有点丢失

我应该送一个空身吗?我需要发送一个而且@Field参数不够吗?

使用Retrofit 1.5.0

2 个答案:

答案 0 :(得分:36)

HTTP的RFC不清楚是否允许DELETE方法拥有请求正文。由于没有改造,改造会引起警告。

但是,您仍然可以使用自定义HTTP方法批注包含一个(假设HTTP客户端支持它)。

package com.myapp;

@Target(METHOD)
@Retention(RUNTIME)
@RestMethod(value = "DELETE", hasBody = true)
public @interface BODY_DELETE {
  String value();
}

现在使用您定义的自定义注释指定您的接口方法。

@FormUrlEncoded
@BODY_DELETE(INetwork.API_BASE_PREFIX + "/memberships.json")
void leave(@Field("id") String id, Callback<?> cb);

答案 1 :(得分:20)

更新了Retrofit 2.0的答案:

Retrofit 2似乎没有@RestMethod,所以这里有效:

@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
void leave(@Field("id") String id, Callback<?> cb);

改装2。+

@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
Callback<?> cb(@Field("id") String id);

和RxRetrofit 2。+

@FormUrlEncoded
@HTTP(method = "DELETE", path = INetwork.API_BASE_PREFIX + "/memberships.json", hasBody = true)
Observable<?> cb(@Field("id") String id);