关于android:HttpDelete与body

HttpDelete with body

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

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

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


您是否尝试过覆盖HttpEntityEnclosingRequestBase,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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方法。我认为抽象类几乎可以为你做所有事情,所以这可能就是所需要的。

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


按照Walter Mudnt的建议,您可以使用此代码。它工作正常,只是在测试我的REST Web服务时做到了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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。

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

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

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

更新:你想要每个HTTP DELETE发送一些正文你可以这样做,例如如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 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
2
3
4
5
6
7
8
9
class MyDelete extends HttpPost{
    public MyDelete(String url){
        super(url);
    }
    @Override
    public String getMethod() {
        return"DELETE";
    }
}

在改造中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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请求冲突。