Android HttpPost failes - 服务器接收空查询字符串参数

时间:2012-04-22 04:11:31

标签: android wcf http rest http-post

我的计算机上有一个简单的WCF Web服务,我已经开发它来为Android和IOS设备提供服务。

该服务有以下单一方法:

[OperationContract]
    [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/?message={message}")]
    string ServiceMessage(string message);

我有3个客户端,一个使用HttpWebRequest的.NET测试客户端工作正常,一个IOS客户端工作正常,一个我用HttpPost和HttpClient类开发的Android客户端失败。

使用Fiddler反向代理我调试了.net客户端的输出:

POST http://127.0.0.1:8888/Service1.svc/?message=_|JSON MESSAGE BODY|_HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:8888
Content-Length: 338
Expect: 100-continue
Connection: Keep-Alive

_|JSON MESSAGE BODY|_

另一方面,这是Android HTTP Post的输出:

POST http://10.0.2.2:8888/Service1.svc/ HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 139
Host: 10.0.2.2:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
Expect: 100-Continue

message=_|JSON MESSAGE BODY|_

正如您所看到的,.Net将消息参数放在帖子顶部而不是 将消息变量名称放在底部,而Android不将消息体放在顶部的Post上,并将消息变量名称放在底部。

这是我的Android帖子代码,

    HttpPost httpPost = new HttpPost(url);      
    String messageBody = "message=" + jsonMessageParameter;
    StringEntity entity = new StringEntity(messageBody);
    httpPost.setEntity(entity);
    httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
    HttpResponse response = hc.execute(httpPost);
    InputStream content = response.getEntity().getContent();
    String json = ConvertStreamToString(content);

使用此代码调用时,将调用server方法,但message方法参数为null。 我尝试使用Uri.Builder类也使得android帖子将消息放在标题中,但并不是很有效。 如果有人可以帮我解决这个问题,我会坚持几个小时。“

提前谢谢你,

詹姆斯

编辑:

我将Android代码更改为:

    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
    nameValuePairs.add(new BasicNameValuePair("message", jsonMessageParameter));

    HttpPost httpPost = new HttpPost(url);
     UrlEncodedFormEntity urlEncodedFromEntity = new UrlEncodedFormEntity(
     nameValuePairs);
     urlEncodedFromEntity.setContentType(new BasicHeader("Content-Type",
     "application/json; charset=utf-8"));

    httpPost.setEntity(urlEncodedFromEntity);

    InputStream postStream = httpPost.getEntity().getContent();
    String postOutput = ConvertStreamToString(postStream);
    HttpResponse response = hc.execute(httpPost);
    InputStream content = response.getEntity().getContent();
    String json = ConvertStreamToString(content);

但是Fiddler的监控仍然如下:

POST http://10.0.2.2:8888/Service1.svc/ HTTP/1.1
Content-Length: 189
Content-Type: application/json; charset=utf-8
Host: 10.0.2.2:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
Expect: 100-Continue

message=_|MESSAGE_JSON|_

2 个答案:

答案 0 :(得分:1)

这里有很多要点。

首先,您专门为您的Android POST正文添加了message=

String messageBody = "message=" + jsonMessageParameter;

这也可能有问题,因为您指定了Content-Type: application/json,但添加了message=您没有提供有效的JSON对象。

第二,为什么.Net实现将JSON对象复制为URL和正文中的参数?对于POST请求,这看起来很奇怪且非常罕见,如果您的JSON对象使URL超过最大URL长度,则会导致问题。

所以我会尝试删除正文中的message=并删除JSON对象作为URL参数,因为处理POST的服务器应该读取正文而不是URL。

答案 1 :(得分:0)

HttpPost是发布,afaik。

String url;
input = url + URLEncoder.encode(messageBody, "utf-8");
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(input);
InputStream stream = httpclient.execute(httpget).getEntity().getContent();
String s = streamToString(stream);
JSONObject jObject = new JSONObject(s); 

这个非常精确的代码(以及一些try / catch)对我来说可用于查询GoogleBooks,可能您可以轻松地将其调整到您的服务中吗?

最好的问候。