DefaultHttpClient 更改响应大小?

Posted

技术标签:

【中文标题】DefaultHttpClient 更改响应大小?【英文标题】:DefaultHttpClient change response size? 【发布时间】:2012-02-08 07:33:46 【问题描述】:

我想做什么


大家好,我正在尝试创建一个应用程序,我可以在其中查看客户给我的订单。为此,我在我的服务器上创建了一个接口,我可以在该接口上发送 post/get/set 请求。服务器的响应是 JSON 格式的。 (供您的信息 atm 仅填写 dummydata)

现在,当我从我的应用程序向服务器发出 get 请求时,我得到了它的响应,但它不完整,大约一半我应该得到的响应不存在! :( 但是当我在浏览器中打开带有 Get-Request 的 URL 时,我得到了完整的响应。

问题


如您所见,这不可能是基于服务器的问题,因为我也尝试通过“curl”来获取请求,并且总是得到完整的响应。

在我的应用程序中,我使用 DefaultHttpClient,所以我认为问题可能只是响应有限制,但我没有找到。

那么我在哪里可以更改这个“响应大小”,还有什么问题导致我没有得到完整的响应!一些好的 code-sn-ps 或任何你能想象到的会有帮助!

在这里,您将找到执行 Get-Request 的 Methode 的代码。

代码


如果您需要更多代码,只需将其写入 cmets!

getOrders()


public void getOrders() 
        Log.d("DataHandlerService", "Aufträge werden geladen");
        Thread t = new Thread() 
            public void run() 

                SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
                String userid = settings.getString("userid", "uid");


                Log.d("DataHandlerService", userid);

                // Download-URL
                String URL = "http://api.i-v-o.ch/users/" + userid
                        + "/assignments.json";
                Log.d("Request-URL", URL);

                DefaultHttpClient client = new DefaultHttpClient();
                HttpResponse response;

                try 
                    HttpGet request = new HttpGet();
                    request.setURI(new URI(URL));
                    request.addHeader("Content-Type",
                            "application/x-www-form-urlencoded");
                    response = client.execute(request);


                    int statuscode = response.getStatusLine().getStatusCode();
                    switch (statuscode) 

                    case 200:

                        if (response != null) 

                            StringBuilder sb = new StringBuilder();
                            BufferedReader rd = new BufferedReader(
                                    new InputStreamReader(response.getEntity()
                                            .getContent()));

                            String line;
                            while ((line = rd.readLine()) != null) 
                                sb.append(line + "\n");
                            
                            String result;
                            result = sb.toString();
                            Log.d("Response", result);
                            JSONReader(result); //here the json will be generated
                        

                        break;

                    case 500:
                        // Error-Handling
                        break;
                    
                 catch (Exception e) 
                    e.printStackTrace();
                    Log.e("DataHandler", "URLConnection-Error" + e);
                

            
        ;
        t.start();
    

这是您要求的响应,就像您看到其中的一部分不存在一样!:

["created_at":"2012-01-06T17:10:00Z","end_datetime":"2008-03-25T13:00:00Z","id":2127,"start_datetime":"2008-03-25T13:00:00Z","updated_at":"2012-01-06T17:10:00Z","title":"2127 Foobar","referee_forename":"Peter","referee_surname":"Gertsch","referee_full_name":"Peter Gertsch","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:03Z","end_datetime":"2008-04-04T12:00:00Z","id":2134,"start_datetime":"2008-04-04T12:00:00Z","updated_at":"2012-01-06T17:10:03Z","title":"2134 Foobar","referee_forename":"Daniel","referee_surname":"Brunner","referee_full_name":"Daniel Brunner","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:03Z","end_datetime":"2008-04-07T12:00:00Z","id":2136,"start_datetime":"2008-04-07T12:00:00Z","updated_at":"2012-01-06T17:10:03Z","title":"2136 Foobar","referee_forename":"Andreas","referee_surname":"Lutz","referee_full_name":"Andreas Lutz","category_title":"Installation - SAT","status_title":"Closed - technisches problem","created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-22T07:00:00Z","id":2144,"start_datetime":"2008-05-22T07:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2144 Foobar","referee_forename":"Pascal","referee_surname":"Pichand","referee_full_name":"Pascal Pichand","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-15T07:00:00Z","id":2145,"start_datetime":"2008-05-15T07:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2145 Foobar","referee_forename":"Hansruedi","referee_surname":"W\u00fcrgler","referee_full_name":"Hansruedi W\u00fcrgler","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-05-26T08:00:00Z","id":2146,"start_datetime":"2008-05-26T08:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2146 Foobar","referee_forename":"Martina","referee_surname":"Issler","referee_full_name":"Martina Issler","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:08Z","end_datetime":"2008-06-03T14:00:00Z","id":2147,"start_datetime":"2008-06-03T14:00:00Z","updated_at":"2012-01-06T17:10:08Z","title":"2147 Foobar","referee_forename":"Matthias ","referee_surname":"Kuhn","referee_full_name":"Matthias  Kuhn","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:12Z","end_datetime":"2008-07-07T07:00:00Z","id":2157,"start_datetime":"2008-07-07T07:00:00Z","updated_at":"2012-01-06T17:10:12Z","title":"2157 Foobar","referee_forename":"Eberhard","referee_surname":"Polatzek","referee_full_name":"Eberhard Polatzek","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:13Z","end_datetime":"2008-07-11T08:00:00Z","id":2161,"start_datetime":"2008-07-11T08:00:00Z","updated_at":"2012-01-06T17:10:13Z","title":"2161 Foobar","referee_forename":"Magali","referee_surname":"Bohin","referee_full_name":"Magali Bohin","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:14Z","end_datetime":"2008-07-25T08:30:00Z","id":2163,"start_datetime":"2008-07-25T08:30:00Z","updated_at":"2012-01-06T17:10:14Z","title":"2163 Foobar","referee_forename":"(Hotel Centrum Griesalp)","referee_surname":"Haltenegg Betriebs AG","referee_full_name":"(Hotel Centrum Griesalp) Haltenegg Betriebs AG","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:16Z","end_datetime":"2008-08-07T09:00:00Z","id":2170,"start_datetime":"2008-08-07T09:00:00Z","updated_at":"2012-01-06T17:10:16Z","title":"2170 Foobar","referee_forename":".","referee_surname":"SAC Hollandiah\u00fctte","referee_full_name":". SAC Hollandiah\u00fctte","category_title":"Installation - SAT","status_title":"Closed - Erfolgreich","created_at":"2012-01-06T17:10:16Z","end_datetime":"2009-05-07T06:30:00Z","i

【问题讨论】:

仅供参考:您阅读HttpResponse 的方式非常疯狂。请改用EntityUtils.toString(HttpEntity) 嘿 Jens,我试过这个,就像你告诉我的那样,当我通过 'response.getEntity().ContentLength();' 获得响应的长度时,我首先发现了一些东西我得到 7046,但是当我检查响应在我将其变为字符串之后的多长时间时,它只有大约 4060,我该如何解决这个问题?? 字节大小并不总是与字符串大小相关,除非您的 JSON 中只有 US-ASCII/Latin-1 或其他 1 字节字符集。您收到什么类型的字符串内容(即您可以发布 JSON 示例输出)。 它以 UTF-8 编码,我将添加 json 我会通过响应,如果你检查链接 i-v-o.ch/users/116/assignments.json 你会得到整个 json。我会把收到的回复发给你! 【参考方案1】:

啊。对,问题不在于您的连接或类似的东西。您的服务正在返回一个数组 - 不是一个对象 - 因此您应该像这样解析它:

HttpResponse response = ...
if (.. validate status ..) 
    JSONArray array = new JSONArray(HttpEntityUtils.toString(response.getEntity()));
    // Your JSONArray is now ready to play with.

并考虑使用 AsyncTask 而不是 Thread,如下所示:

class AssignmentsTask extends AsyncTask<String, Void, JSONArray> 
    @Override
    protected JSONArray doInBackground(String... params) 
        final String url = "http://api.i-v-o.ch/users/" + params[0]
                + "/assignments.json";
        try 
            HttpResponse response = mClient.execute(new HttpGet(url));
            if (response.getStatusLine().getStatusCode() == 200) 
                return new JSONArray(EntityUtils.toString(response.getEntity()));
             else 
                Log.w(TAG, "Error receiving assignments for " + params[0] + ", " + response.getStatusLine());
            
         catch (ClientProtocolException e) 
            Log.w(TAG, "Proto: Error fetching assignments for " + params[0], e);
         catch (IOException e) 
            e.printStackTrace();
            Log.w(TAG, "IO: Error reading assignments for " + params[0], e);
         catch (ParseException e) 
            Log.w(TAG, "Parse: Error parsing assignments for " + params[0], e);
         catch (JSONException e) 
            Log.w(TAG, "JSON: Error parsing JSON for " + params[0], e);
        
        return null;
    

    @Override
    protected void onPostExecute(JSONArray result) 
        // Stuff that handles the resulting JSONObject on
        // the UI-thread goes here (i.e. update View:s)

        // result is null if the operation failed
    

并为用户“116”检索订单:

new AssignmentsTask().execute("116");

【讨论】:

我收到此错误 :( '02-08 15:41:27.960: W/System.err(31510): java.lang.IllegalStateException: Content has been used' because this line 'JSONArray数组 = 新 JSONArray(HttpEntityUtils.toString(response.getEntity()));' :( 好吧,你只能消费(即读取流的内容)一次 HttpEntity,就像上面的例子一样。调用 EntityUtils.toString(HttpEntity) 将使用内容并将响应作为字符串返回给 JSONArray:s 构造函数。【参考方案2】:

响应大小应由您联系的网络服务器提供。你可以阅读response size using:

httpResponse.getEntity().getContentLength()

此外,可能发生的情况是连接超时,使客户端无法接收响应的所有数据。在这种情况下,请尝试using a timeout that is long enough 以确保您获得所有数据。

如果您的 json 太大,那么在移动环境中期望所有数据都来自单个请求并不是一个好主意,那么您可能必须设计一个可以为您提供大量响应的 Web 服务器,您然后将需要第一个块,然后是另一个块,等等。

Usually, the http protocole's partial content is the answer for that problem.

【讨论】:

以上是关于DefaultHttpClient 更改响应大小?的主要内容,如果未能解决你的问题,请参考以下文章

响应引导时更改 <h1> 标记的大小 [重复]

DefaultHttpClient 到 AndroidHttpClient

DefaultHttpClient使用

DefaultHttpClient 类 Android 中的超时

Android 上 DefaultHttpClient 中连接和套接字超时的默认值是啥?

REST API 响应主体相同但响应大小不同