【问题标题】:executing http POST returns HTML instead of JSON执行 http POST 返回 HTML 而不是 JSON
【发布时间】:2013-07-15 02:46:57
【问题描述】:

编辑完全重新处理问题以便更好地理解

我必须使用 2 个 POST 参数查询给定的 url http://api.bf3stats.com/pc/player/:'player'(用于玩家名称)和 'opt'(用于选项)。我已经在http://www.requestmaker.com/ 上使用以下数据对其进行了测试:player=Zer0conf&opt=all。我得到了正确的 JSON 响应(以为我不知道他们的网站如何执行查询,我猜是 php)。现在我正在尝试在 Android 中做同样的事情:

  private StringBuilder inputStreamToString(InputStream is) {
       //this method converts an inputStream to String representation
    String line = "";
    StringBuilder total = new StringBuilder();

    BufferedReader rd = new BufferedReader(new InputStreamReader(is));

    try {
        while ((line = rd.readLine()) != null) {
            total.append(line);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return total;
}

这就是我提出请求的方式:

 public void postData(String url, String name) {

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);

    try {

        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                    //qname is a String containing a correct player name
        nameValuePairs.add(new BasicNameValuePair("player", qname));
        nameValuePairs.add(new BasicNameValuePair("opt", "all"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        HttpResponse response = httpclient.execute(httppost);
        //test is just a string to check the result, which should be in JSON format
        test = inputStreamToString(response.getEntity().getContent())
                .toString();

    } catch (ClientProtocolException e) {

    } catch (IOException e) {

    }
}

我在“测试”字符串中得到的不是 JSON,而是某些 bf3stats 页面的完整 HTML 标记。我的请求可能有什么问题?

【问题讨论】:

  • 看看答案here有没有帮助。

标签: android json http-post


【解决方案1】:

您需要在请求标头中为要发送的数据类型设置内容类型"application/x-www-form-urlencoded"

我针对上述数据测试了您的 API,它工作正常,并且我收到了大量数据作为响应。你可以找到它here

你可以试试下面的代码:

public  String postDataToServer(String url) throws Throwable
    {

    HttpPost request = new HttpPost(url);
    StringBuilder sb=new StringBuilder();

    String requestData = prepareRequest();
    StringEntity entity = new StringEntity(requestData);
                         entity.setContentType("application/x-www-form-urlencoded;charset=UTF-8");//text/plain;charset=UTF-8
                         request.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE);

                         request.setHeader("Accept", "application/json");
                         request.setEntity(entity); 
                         // Send request to WCF service 
                         HttpResponse response =null;
                         DefaultHttpClient httpClient = new DefaultHttpClient();
                         //DefaultHttpClient httpClient = getNewHttpClient();
                         HttpConnectionParams.setSoTimeout(httpClient.getParams(), 10*1000); 
                         HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),10*1000); 
                         try{

                         response = httpClient.execute(request); 
                         }
                         catch(SocketException se)
                         {
                             Log.e("SocketException", se+"");
                             throw se;
                         }
                         /* Patch to prevent user from hitting the request twice by clicking 
                          * the view [button, link etc] twice.
                          */
                         finally{
                         }



    InputStream in = response.getEntity().getContent();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    String line = null;
    while((line = reader.readLine()) != null){
        sb.append(line);

    }
    Log.d("response in Post method", sb.toString()+"");
    return sb.toString();
    }

    public String prepareRequest()
    {

        return "player=Zer0conf&opt=all";
    }

编辑:您的 Web 服务出现错误 Expectation Failed error- 417。所以我们需要在我们的请求中再添加一个参数。它是 request.getParams().setParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, Boolean.FALSE); 。我已经用这个更新了上面的代码。现在它工作正常。

响应看起来像这样。

希望这会有所帮助。

干杯
N_JOY

【讨论】:

  • 我使用了您的代码(添加了播放器名称作为动态参数)并且仍然在“测试”字符串中获得了一些 HTML 内容...这是我的完整课程:pastebin.com/QBpTcjAG 也许我错了在某个时候?
  • 真的很奇怪..刚刚执行了我在pastebin上发布的代码,没有错误,但是HTML而不是JSON..
  • 我们在请求中遗漏了一个参数。在答案中更新了相同的内容。
  • 非常感谢,终于在“test”字符串中得到了正确的响应!还有一个小问题:现在我的类看起来像pastebin.com/icV8H5vj(请检查 OnPostExecute 方法)由于某种原因,我无法将接收到的数据传递给另一个 Activity,我的应用程序在日志消息“开始活动”之后退出。我又错过了什么吗?
  • OnPostexecute() 看起来不错。我想不需要 super.onPostExecute() 所以删除它。并且不建议以字符串的形式传递大量数据。为此创建一些 javaBean 类或为其找到一些替代方法。
【解决方案2】:

尝试在浏览器中查看url,我相信有一个!DOCTYPE声明,肯定不能解析为JSON对象。

【讨论】:

  • 如果我尝试在浏览器中打开 URL,我被重定向到主页,你确定这意味着 url 不正确吗?我过去曾经收到一些 JSON 响应,但我使用的系统完全不同,您无法在浏览器中打开请求 url..
  • @Maver1ck 如果该 url 需要某种会话变量(如登录凭据),则无法直接使用浏览器查看它,但您可以使用 eclipse 调试工具或仅验证字符串 jsonResults将其注销以查看收到的响应。无论如何,正确的 JSON 响应不应包含 DOCTYPE 声明。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2022-01-01
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多