2010-09-22 34 views
38

我试图使用HttpDelete对象来调用Web服务的删除方法。 Web服务的代码从消息正文中解析JSON。但是,我无法理解如何将一个主体添加到HttpDelete对象。有没有办法做到这一点?与身体HttpDelete

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

如果没有办法为HttpDelete对象设置主体,那么请将我链接到使用超类HttpDelete的资源,以便我可以设置方法(删除)并设置主体。我知道这并不理想,但在这一点上,我无法改变网络服务。

回答

86

您是否尝试过重写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 -lookalike具有setEntity方法。我认为抽象类为你做了几乎所有的事情,所以这可能是所有需要的。代码基于this source to HttpPost that Google turned up

+4

你摇滚的家伙!谢谢! – 2013-05-22 03:32:52

+0

呃!这似乎不适用于HttpURLConnection。我得到“java.net.ProtocolException:DELETE不支持写入”。 http://stackoverflow.com/questions/10338615/sending-http-delete-request-in-android – 2013-09-30 14:45:06

+0

我与斯科特......我如何做到这一点与HttpURLConnection?我必须重写我的网络代码才能使用Apache HTTP? – 2014-03-03 16:37:09

4

HTTP DELETE请求中,对于身体是否被允许或不允许有不同的解释。例如,请参见this。在HTTP 1.1 specification它没有明确禁止。我认为你不应该在HTTP DELETE中使用主体

Nevertherless我认为你应该使用URL像mysite/myobject/objectIdshop.com/order/1234),其中objectId网址的一部分)是附加信息。作为替代,您可以使用URL参数mysite/myobject?objectName=table&color=redHTTP DELETE请求中的服务器发送附加信息。以'?'开头的部分是urlencoded参数,分为dy'&'。

如果你想发送更复杂的信息,您可以将数据转换成JSON与尊重DataContractJsonSerializerJavaScriptSerializer然后发送转换后的数据(这是我的名字myJsonData后的字符串),也为参数:mysite/myobject?objectInfo=myJsonData

如果您需要发送太多的附加数据作为HTTP DELETE请求的一部分,以便您对URL长度有问题,那么您应该更好地更改应用程序的设计。

修订:IY你想发送每个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 Service需要HTTP DELETE请求体中的数据是不好设计的。

+1

-1。提问者很清楚地说他不能改变网络服务,他可能也没有设计它。由于这篇文章中的每个建议都涉及到代码不在提问者控制下的情况,所以这对于手头的情况是完全没有帮助的。 – 2010-09-29 09:57:11

+0

为了什么是值得的,我并不同意你原则上的观点;需要DELETE方法的Web服务可能设计不佳。尽管如此,问如何与一个设计不好并且可能不符合标准的Web服务进行接口是合理的,这就是我解释这个问题的方式。 – 2010-09-29 10:16:48

+0

@Walter Mundt:如果有一个**需要在HTTP DELETE中发送主体,我添加了一个示例,其中一种可能的方式是执行此操作。 – Oleg 2010-09-29 10:57:12

3

使用此,

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

继沃尔特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();在改造

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

+1

谢谢你,你摇滚。:) – 2015-06-23 11:58:32

0

你有触发条件,通过东西,可能必须做一些过滤的网址/头/ body删除触发器,

除非删除url/body/header的唯一性不足以与post或get请求发生冲突。