42

我正在尝试使用 HttpDelete 对象来调用 Web 服务的删除方法。Web 服务的代码从消息的正文中解析 JSON。但是,我不明白如何将正文添加到 HttpDelete 对象。有没有办法做到这一点?

使用 HttpPut 和 HttpPost,我调用 setEntity 方法并传入我的 JSON。HttpDelete 似乎没有任何此类方法。

如果无法为 HttpDelete 对象设置主体,请您将我链接到使用 HttpDelete 超类的资源,以便我可以设置方法(删除)并设置主体。我知道这并不理想,但此时我无法更改 Web 服务。

4

5 回答 5

96

您是否尝试过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方法的 -lookalike。我认为抽象类几乎可以为您完成所有工作,因此这可能就是您所需要的。

FWIW,代码基于谷歌出现的 HttpPost 的这个源

于 2010-09-29T10:03:21.230 回答
9

按照 Walter Mudnt 的建议,您可以使用此代码。它有效,只是在测试我的 REST web 服务时成功。

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

于 2014-04-10T10:03:07.633 回答
4

HTTP DELETE对于请求中是否允许该主体的问题,有不同的解释。参见这个例子。在HTTP 1.1 规范中,它没有被明确禁止。在我看来,你不应该HTTP DELETE.

尽管如此,我认为您应该使用mysite/myobject/objectId( shop.com/order/1234) 之类的 URL,其中objectId( url 的一部分) 是附加信息。作为替代方案,您可以使用URL 参数:mysite/myobject?objectName=table&color=red在请求中向服务器发送附加信息HTTP DELETE。以“?”开头的部分 是由dy '&' 分隔的urlencoded参数。

如果您想发送更复杂的信息,您可以将数据转换为关于DataContractJsonSerializerJavaScriptSerializer的 JSON,然后将转换后的数据(我myJsonData稍后命名的字符串)也作为参数发送:mysite/myobject?objectInfo=myJsonData

如果您需要发送过多的附加数据作为HTTP DELETE请求的一部分,从而导致 URL 长度出现问题,那么您最好更改应用程序的设计。

更新:如果您确实希望通过 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

完整的代码可能会更复杂一些,但这个已经可以工作了。尽管如此,我仍然要说,HTTP DELETE 请求正文中的 Web 服务所需的数据设计不佳。

于 2010-09-29T09:52:49.710 回答
3

用这个,

class MyDelete extends HttpPost{
    public MyDelete(String url){
        super(url);
    }
    @Override
    public String getMethod() {
        return "DELETE";
    }
}
于 2013-06-06T10:19:10.487 回答
0

改造中

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 请求发生冲突。

于 2017-01-06T15:24:25.543 回答