web-dev-qa-db-ja.com

非同期FormUrlEncodedDELETE呼び出しに対してIllegalArgumentException例外をスローするレトロフィット

非同期のPOSTと、Retrofitを使用してエンコードされたフォームURLであるDELETEをAndroid 4.4で作成しようとしています。

これが私のクライアントです-

@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パラメーターでは不十分ですか?

Retrofit1.5.0の使用

12
Rickster

HTTPのRFCは、DELETEメソッドが要求本文を持つことを許可されているかどうかについて明確ではありません。レトロフィットは、エラーが発生しないため、注意が必要です。

ただし、カスタムHTTPメソッドアノテーションを使用して、1つを含めることができます(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);
36
Jake Wharton

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

およびRxRetrofit2。+の場合

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