【问题标题】:Android HttpPost failes - server receives null query string parameterAndroid HttpPost 失败 - 服务器接收到空查询字符串参数
【发布时间】:2012-05-03 03:45:19
【问题描述】:

我的机器上有一个简单的 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 客户端运行良好,一个 Android 客户端使用 HttpPost 和 HttpClient 类开发失败。

使用 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 将 message 参数放在 Post 的顶部,并没有 将消息变量名放在底部,而 Android 不会将消息正文放在 Post 顶部,而是将消息变量名放在底部。

这是我的安卓邮政编码,

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

使用此代码调用时,调用了服务器方法,但消息方法参数为空。 我尝试使用 Uri.Builder 类也使 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|_

【问题讨论】:

    标签: android wcf http rest http-post


    【解决方案1】:

    这里有很多要点。

    首先,您专门将message= 添加到您的 Android POST 正文中:

    String messageBody = "message=" + jsonMessageParameter;
    

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

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

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

    【讨论】:

    • 但是如果服务方法接收到几个查询字符串参数怎么办?
    • 使用 UrlEncodedFormEntity 而不是 StringEntity,这样会产生类似 param1=value1&param2=value2...的 body...
    • 最后,我似乎没有在服务器端正确读取 JSON。对我有用的唯一方法是在服务器端接收 Stream 对象,这使我可以阅读消息正文。
    【解决方案2】:

    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,也许您可​​以不费吹灰之力地将其调整为您的服务?

    最好的问候。

    【讨论】:

    • 但是如果服务方法接收到几个查询字符串参数,那你怎么发布呢?
    猜你喜欢
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    相关资源
    最近更新 更多