HttpDelete与身体
我试图使用HttpDelete对象来调用Web服务的删除方法。 Web服务的代码parsing消息正文中的JSON。 但是,我无法理解如何将身体添加到HttpDelete对象。 有没有办法做到这一点?
使用HttpPut和HttpPost,我调用setEntity方法并传入我的JSON。 似乎没有任何这样的HttpDelete的方法。
如果没有办法设置一个HttpDelete对象的主体,请把我链接到一个使用超类HttpDelete的资源,以便我可以设置方法(删除)并设置一个主体。 我知道这是不理想的,但在这一点上,我不能改变networking服务。
你有没有尝试覆盖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(); } }
这将创build一个具有setEntity
方法的HttpDelete
Lookalike。 我认为抽象类为你做了几乎所有事情,所以这可能是所有需要的。
FWIW,这个代码是基于这个源码给谷歌出现的HttpPost 。
遵循Walter Mudntbuild议,您可以使用此代码。 它的工作原理,只是在testing我的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();
在HTTP DELETE
请求中是否允许主体的问题有不同的解释。 看到这个例子。 在HTTP 1.1规范中没有明确禁止。 在我看来,你不应该在HTTP DELETE
使用body 。
Nevertherless我认为你应该使用像mysite/myobject/objectId
( shop.com/order/1234
) 的URL ,其中objectId
( url的一部分 )是附加信息。 作为替代,您可以使用URL参数 : mysite/myobject?objectName=table&color=red
在HTTP DELETE
请求中将附加信息发送到服务器。 以'?'开头的部分 是urlencoded参数将dy'&'分开。
如果你想发送更复杂的信息,你可以把数据转换成JSON的DataContractJsonSerializer或JavaScriptSerializer ,然后发送转换的数据(一个string,我以后名为myJsonData
)也作为参数: mysite/myobject?objectInfo=myJsonData
。
如果您需要发送过多的附加数据作为HTTP DELETE
请求的一部分,以便您对URL长度有问题,那么您应该更好地更改应用程序的devise。
更新 :你是否想发送一些身体每个HTTP删除你可以做到这一点,例如像下面
// 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请求体中的数据不好devise。
用这个,
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/标题/正文删除触发器,
除非删除url / body / header是唯一的,不会与post或get请求发生冲突。