web-dev-qa-db-ja.com

本文付きのHttpDelete

HttpDeleteオブジェクトを使用してWebサービスの削除メソッドを呼び出そうとしています。 Webサービスのコードは、メッセージの本文からJSONを解析します。しかし、HttpDeleteオブジェクトに本文を追加する方法を理解できていません。これを行う方法はありますか?

HttpPutとHttpPostを使用して、setEntityメソッドを呼び出し、JSONを渡します。 HttpDeleteにはそのようなメソッドはないようです。

HttpDeleteオブジェクトの本文を設定する方法がない場合は、HttpDeleteのスーパークラスを使用するリソースにリンクして、メソッド(削除)を設定し、本文を設定できるようにしてください。理想的ではないことはわかっていますが、現時点ではWebサービスを変更できません。

40
Andrew

次のように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へのこのソース に基づいています。

93
Walter Mundt

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

9
dazito

HTTP DELETEリクエストで本文が許可されているかどうかの質問には、異なる解釈があります。たとえば this を参照してください。 HTTP 1.1仕様 では、明示的に禁止されていません。私の意見では、あなたHTTP DELETEでbodyを使用すべきではありません。

それにもかかわらず、mysite/myobject/objectIdshop.com/order/1234)のようなURLを使用する必要があると思います。ここで、objectIda 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リクエストの本文に必要なデータは設計が悪いと言い続けています。

4
Oleg

これを使って、

class MyDelete extends HttpPost{
    public MyDelete(String url){
        super(url);
    }
    @Override
    public String getMethod() {
        return "DELETE";
    }
}
2
Ishan Liyanage

改造中

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リクエストと衝突しないほど十分にユニークでない限り。

0