【问题标题】:Android: HttpPost content type header and body different between wifi and 3gAndroid:wifi和3g之间的HttpPost内容类型标题和正文不同
【发布时间】:2012-06-24 04:32:28
【问题描述】:

一段时间以来一直试图弄清楚这个问题是什么。我正在使用 HttpClient.execute 向我的服务器 api 发出带有 json 正文的发布请求。在普通 wifi 和大多数 3g 下工作正常,但特别是在具有 AT&T 数据计划并且它在 3g 上的手机上,当我尝试执行请求时,我收到了一个 HttpResponseException,状态代码为 422。对 422 做了一些研究,它说它是由于到:

“422 Unprocessable Entity (WebDAV) (RFC 4918),请求格式正确,但由于语义错误而无法遵循。”

所以我猜测请求的发出方式出了点问题,但我在形成请求时正在做同样的事情,无论我是使用 wifi 还是 3g。关于可能导致此错误的任何想法?

编辑: 看起来我的服务器正在使用伪造保护来捕捉帖子。关闭它,错误停止,但api没有通过。挖得更深一点,打印出服务器实际接收到的内容,比较了 wifi 的开启和关闭,发现了两个不同之处。首先,3g 上的 body 是空的,好像它被阻止发送。二、header改变了正在发送的内容类型:

wifi:“HTTP_CONTENT_TYPE”=>“应用程序/json” att 3g: "HTTP_CONTENT_TYPE"=>"text/plain; charset=ISO-8859-1,application/json"

我期待“应用程序/json”,因为我正在像这样设置我的连接:

StringEntity se = new StringEntity(json.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

任何想法为什么当我转移到 3g 时情况会发生变化?

更新:运行 tcpdump,看起来我从 android 发送的内容在 wifi 和 3g 之间完全相同,所以似乎是提供者正在更改我的数据。除 HTTPS 之外还有其他建议的策略吗?

【问题讨论】:

  • 假设这是服务器收到的内容(与电话发送的内容相比),听起来您在通过运营商的代理时可能会遭受一些重写。如果您是 root 用户,您可以运行 tcpdump 并确定您要发送的内容(有非 root 用户的方式,但它们非常棘手)如果您已为此设置,使用 https 可能是一种解决方法。

标签: android json http-post 3g antiforgerytoken


【解决方案1】:

解决了!

旧代码:

    mPost = new HttpPost(ur);
    StringEntity se = new StringEntity(json.toString());
    se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
    mPost.setEntity(se);

新代码:

    mPost = new HttpPost(ur);
    ByteArrayEntity baEntity = new ByteArrayEntity(json.toString().getBytes("UTF8"));
    baEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
    mPost.setEntity(baEntity);

看起来很像使用 ByteArrayEntity 而不是 StringEntity,因为我的帖子正文使其适用于 3g。不确定为什么在使用 StringEntity 时 wifi 和 3g 之间的 tcpdump 看起来完全一样,但它似乎已经解决了问题,所以我没有抱怨。

【讨论】:

  • 谢谢你。在调试移动数据时遇到了麻烦,这救了我的命:)
猜你喜欢
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
相关资源
最近更新 更多