我正在尝试使用HttpDelete对象来调用Web服务的delete方法。 Web服务的代码从消息的正文中解析JSON。但是,我无法理解如何向HttpDelete对象添加主体。有没有办法做到这一点?
使用HttpPut和HttpPost,我调用setEntity方法并传入我的JSON。 HttpDelete似乎没有任何此类方法。
如果无法为HttpDelete对象设置正文,请将我链接到使用超类HttpDelete的资源,以便我可以设置方法(删除)并设置正文。我知道这不太理想,但此时我无法改变网络服务。
答案 0 :(得分:91)
您是否尝试过覆盖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
方法的相似内容。我认为抽象类几乎可以为你做所有事情,所以这可能就是所需要的。
答案 1 :(得分: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();
答案 2 :(得分:4)
在HTTP DELETE
请求中是否允许正文的问题有不同的解释。例如,请参阅this。在HTTP 1.1 specification中没有明确禁止。在我看来,不应在HTTP DELETE
中使用正文。
Nevertherless我认为您应该使用mysite/myobject/objectId
(shop.com/order/1234
)之类的网址,其中objectId
(网址的一部分)是附加信息。作为替代方案,您可以使用网址参数:mysite/myobject?objectName=table&color=red
在HTTP DELETE
请求中向服务器发送附加信息。以“?”开头的部分是urlencoded参数分配dy'&'。
如果要发送更复杂的信息,可以将数据转换为DataContractJsonSerializer或JavaScriptSerializer的JSON,然后发送转换后的数据(我之后命名为myJsonData
的字符串)也作为参数:mysite/myobject?objectInfo=myJsonData
。
如果您需要发送过多的附加数据作为HTTP DELETE
请求的一部分,这样您就会遇到网址长度问题,那么您应该更好地更改应用程序的设计。
更新:您确实希望每个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请求体内的数据设计不好。
答案 3 :(得分:3)
使用此,
class MyDelete extends HttpPost{
public MyDelete(String url){
super(url);
}
@Override
public String getMethod() {
return "DELETE";
}
}
答案 4 :(得分: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进行一些过滤来移除触发器,
除非删除网址/正文/标题的唯一性足以不与帖子或获取请求发生冲突。