12

我正在尝试制作一个异步 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 参数不够?

使用改造 1.5.0

4

2 回答 2

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);
于 2014-03-22T07:44:26.577 回答
23

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);
于 2016-03-30T01:35:02.353 回答