HttpDeleteオブジェクトを使用してWebサービスの削除メソッドを呼び出そうとしています。 Webサービスのコードは、メッセージの本文からJSONを解析します。しかし、HttpDeleteオブジェクトに本文を追加する方法を理解できていません。これを行う方法はありますか?
HttpPutとHttpPostを使用して、setEntityメソッドを呼び出し、JSONを渡します。 HttpDeleteにはそのようなメソッドはないようです。
HttpDeleteオブジェクトの本文を設定する方法がない場合は、HttpDeleteのスーパークラスを使用するリソースにリンクして、メソッド(削除)を設定し、本文を設定できるようにしてください。理想的ではないことはわかっていますが、現時点ではWebサービスを変更できません。
次のようにHttpEntityEnclosingRequestBase
をオーバーライドしてみましたか?
import org.Apache.http.client.methods.HttpEntityEnclosingRequestBase;
import Java.net.URI;
import org.Apache.http.annotation.NotThreadSafe;
@NotThreadSafe
class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
public static final String METHOD_NAME = "DELETE";
public String getMethod() { return METHOD_NAME; }
public HttpDeleteWithBody(final String uri) {
super();
setURI(URI.create(uri));
}
public HttpDeleteWithBody(final URI uri) {
super();
setURI(uri);
}
public HttpDeleteWithBody() { super(); }
}
これにより、HttpDelete
メソッドを持つsetEntity
に似たものが作成されます。抽象クラスはあなたのためにほとんどすべてを行うと思うので、それだけで十分かもしれません。
FWIW、コードは Googleが確認したHttpPostへのこのソース に基づいています。
Walter Mudntのアドバイスに従って、このコードを使用できます。それは機能し、私のREST webservice。
_try {
HttpEntity entity = new StringEntity(jsonArray.toString());
HttpClient httpClient = new DefaultHttpClient();
HttpDeleteWithBody httpDeleteWithBody = new HttpDeleteWithBody("http://10.17.1.72:8080/contacts");
httpDeleteWithBody.setEntity(entity);
HttpResponse response = httpClient.execute(httpDeleteWithBody);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
_
応答にアクセスするには、次のようにします。response.getStatusLine();
HTTP DELETE
リクエストで本文が許可されているかどうかの質問には、異なる解釈があります。たとえば this を参照してください。 HTTP 1.1仕様 では、明示的に禁止されていません。私の意見では、あなたはHTTP DELETE
でbodyを使用すべきではありません。
それにもかかわらず、mysite/myobject/objectId
(shop.com/order/1234
)のようなURLを使用する必要があると思います。ここで、objectId
(a urlの一部)は追加情報。別の方法として、URLパラメータ:mysite/myobject?objectName=table&color=red
を使用して、HTTP DELETE
リクエストで追加情報をサーバーに送信できます。 「?」で始まる部分 rlencoded パラメータがdy '&'に分割されています。
より複雑な情報を送信する場合は、データを DataContractJsonSerializer または JavaScriptSerializer に関してJSONに変換し、変換されたデータ(後でmyJsonData
という名前の文字列)を送信できます。パラメータとしても:mysite/myobject?objectInfo=myJsonData
。
HTTP DELETE
リクエストの一部として大量の追加データを送信する必要があり、URLの長さに問題がある場合は、アプリケーションの設計を変更する必要があります。
[〜#〜] updated [〜#〜]:HTTP DELETEごとに本文を送信したい場合は、たとえば次のように実行できます
// somewhere above add: using System.Net; and using System.IO;
WebClient myWebClient = new WebClient ();
// 1) version: do simple request
string t= myWebClient.UploadString ("http://www.examples.com/", "DELETE", "bla bla");
// will be send following:
//
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Expect: 100-continue
// Connection: Keep-Alive
//
//bla bla
// 2) version do complex request
Stream stream = myWebClient.OpenWrite ("http://www.examples.com/", "DELETE");
string postData = "bla bla";
byte[] myDataAsBytes = Encoding.UTF8.GetBytes (postData);
stream.Write (myDataAsBytes, 0, myDataAsBytes.Length);
stream.Close (); // it send the data
// will be send following:
//
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Expect: 100-continue
//
// bla bla
// 3) version
// create web request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create ("http://www.examples.com/");
webRequest.Method = "DELETE";
webRequest.ServicePoint.Expect100Continue = false;
// post data
Stream requestStream = webRequest.GetRequestStream ();
StreamWriter requestWriter = new StreamWriter (requestStream);
requestWriter.Write (postData);
requestWriter.Close ();
//wait for server response
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse ();
// send following:
// DELETE http://www.examples.com/ HTTP/1.1
// Host: www.examples.com
// Content-Length: 7
// Connection: Keep-Alive
//
// bla bla
完全なコードはもう少し複雑になる可能性がありますが、これはすでに機能します。それにもかかわらず、私はWebサービスがHTTP DELETEリクエストの本文に必要なデータは設計が悪いと言い続けています。
これを使って、
class MyDelete extends HttpPost{
public MyDelete(String url){
super(url);
}
@Override
public String getMethod() {
return "DELETE";
}
}
改造中
import okhttp3.Request;
private final class ApiInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request oldRequest = chain.request();
Request.Builder builder = oldRequest.newBuilder();
if(condition) {
return chain.proceed(builder.build().newBuilder().delete(builder.build().body()).build());
}
return chain.proceed(builder.build());
}
}
何かを介して条件をトリガーする必要があり、潜在的にトリガーを削除するためにurl/header/bodyのフィルタリングを行う必要があります。
削除url/body/headerがpostまたはgetリクエストと衝突しないほど十分にユニークでない限り。