使用输入流直接解析 json



我正在做一个 api 调用,作为回应,我得到了 json。因此,我想直接通过输入流解析它,这样就不需要将其存储在内存中。为此,我正在尝试使用 JSONReader,但我无法用于小于 11 的 api。所以我不知道如何进行。我希望从 2.0 版本开始完成。即使通过 JsonReader 解析也不起作用。我想要GSON解析器,但我没有得到如何使用输入流实现相同的功能。

编辑:我的代码相同:

HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
          HttpResponse response = client.execute(httpGet);
          StatusLine statusLine = response.getStatusLine();
          int statusCode = statusLine.getStatusCode();
          Log.e("123", "Status code ----------- "+statusCode);
          if (statusCode == 200) { 
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();

            // for showing it on textview i am storing in in builder
            BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
            String line;
            while ((line = bReader.readLine()) != null) {
              builder.append(line);
            }
//////////// 
            JsonReader reader = new JsonReader(new InputStreamReader(content));
            reader.setLenient(true);
            readGson(reader);
          } else {
            Log.e("TAG", "Failed to download file");
          }
        } catch (ClientProtocolException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
        return builder.toString();
      }
private void readGson(JsonReader reader) {
    // TODO Auto-generated method stub
    Log.e("TAG", "inidde readgson"+reader);
                 try {
                     Log.e("TAG", "inside try");
                    reader.beginObject();
                    Log.e("123", "inside try  ");
                     while(reader.hasNext()){
                         Log.e("TAG", "reader values"+reader);
                         String name = reader.nextName();
                         if (name.equals("max_id")) {
                             long max_id = reader.nextLong();
                             Log.e("TAG", "sdbfhsajfgsdjbgksdfjv------------------"+max_id);
                           }  else {
                               Log.e("TAG", "c skfnvklsfvn skip value");
                             reader.skipValue();
                           }
                     }
                     reader.endObject();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    Log.e("TAG", "inside catch");
                    e.printStackTrace();
                }
}

输出:

    01-28 10:20:53.519: E/TAG(420): Status code ----------- 200
01-28 10:20:53.679: E/TAG(420): inidde readgsonJsonReader at line 1 column 1
01-28 10:20:53.679: E/TAG(420): inside try
01-28 10:20:53.679: E/TAG(420): inside catch
01-28 10:20:53.679: W/System.err(420): java.io.EOFException: End of input at line 1 column 1
01-28 10:20:53.689: W/System.err(420):  at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:954)
01-28 10:20:53.689: W/System.err(420):  at com.google.gson.stream.JsonReader.consumeNonExecutePrefix(JsonReader.java:405)
01-28 10:20:53.689: W/System.err(420):  at com.google.gson.stream.JsonReader.peek(JsonReader.java:364)
01-28 10:20:53.689: W/System.err(420):  at com.google.gson.stream.JsonReader.expect(JsonReader.java:337)
01-28 10:20:53.689: W/System.err(420):  at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:322)
01-28 10:20:53.689: W/System.err(420):  at com.example.httpconnectiondemo.MainActivity.readGson(MainActivity.java:136)
01-28 10:20:53.699: W/System.err(420):  at com.example.httpconnectiondemo.MainActivity.readTwitterFeed(MainActivity.java:116)
01-28 10:20:53.699: W/System.err(420):  at com.example.httpconnectiondemo.MainActivity.onCreate(MainActivity.java:64)
01-28 10:20:53.699: W/System.err(420):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-28 10:20:53.699: W/System.err(420):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-28 10:20:53.699: W/System.err(420):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-28 10:20:53.699: W/System.err(420):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-28 10:20:53.699: W/System.err(420):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-28 10:20:53.699: W/System.err(420):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-28 10:20:53.699: W/System.err(420):  at android.os.Looper.loop(Looper.java:123)
01-28 10:20:53.699: W/System.err(420):  at android.app.ActivityThread.main(ActivityThread.java:3683)
01-28 10:20:53.710: W/System.err(420):  at java.lang.reflect.Method.invokeNative(Native Method)
01-28 10:20:53.710: W/System.err(420):  at java.lang.reflect.Method.invoke(Method.java:507)
01-28 10:20:53.710: W/System.err(420):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-28 10:20:53.710: W/System.err(420):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-28 10:20:53.710: W/System.err(420):  at dalvik.system.NativeStart.main(Native Method)

提前谢谢。

您以

错误的方式使用了content流。看标记的线条:

InputStream content = entity.getContent();
// (1)
BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = bReader.readLine()) != null) {
    builder.append(line);
}
// (2)
JsonReader reader = new JsonReader(new InputStreamReader(content));
reader.setLenient(true);
readGson(reader);

这里的问题是您将同一流包装两次(在标记的行上)。

  • 第一次换行后,您将通过流收集行并将它们连接成builder。您必须意识到,实际上bReader只是content流的包装器。因此,当您收集线条时,content流中的内容会被吃掉。因此,当content流位于输入末尾时,条件(line = ...) != null false
  • 然后再次包装content流 - 用于解析 JSON 内容。但是流已经位于此处输入的末尾,因此 JSON 读取器无需使用任何内容。这正是这句话的意思:java.io.EOFException: End of input at line 1 column 1你的例外。

您所要做的就是只通读一次content流。因此,您在这里有几种选择:

  • 不要将收到的内容保存到String。删除第一个包装和使用builder构建响应字符串的循环。如果这不是一个选项,那么我建议:
  • 将整个响应保存到String。注意:您可以使用 EntityUtils 类执行此操作,因为它将为您完成工作:

    HttpEntity entity = response.getEntity();
    // All the work is done for you here :)
    String jsonContent = EntityUtils.toString(entity);
    // Create a Reader from String
    Reader stringReader = new StringReader(jsonContent);
    // Pass the string reader to JsonReader constructor
    JsonReader reader = new JsonReader(stringReader);
    reader.setLenient(true);
    readGson(reader);
    ...
    // at the end of method return the JSON response
    return jsonContent;
    

相关内容

  • 没有找到相关文章

最新更新