直接使用输入流解析json [英] Parsing json directly using input stream

查看:166
本文介绍了直接使用输入流解析json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



编辑:
我的代码相同:

  HttpClient client = new DefaultHttpClient(); 
HttpGet httpGet = new HttpGet(url);

尝试{
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
Log.e(123,状态码-----------+ statusCode);
if(statusCode == 200){
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();


//用于在textview上显示它我正在存储在构建器中
BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
字符串行; ((line = bReader.readLine())!= null){
builder.append(line);
while
}

////////////
JsonReader reader = new JsonReader(new InputStreamReader(content));
reader.setLenient(true);
readGson(reader);
} else {
Log.e(TAG,无法下载文件);
}
} catch(ClientProtocolException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
return builder.toString();

$ b private void readGson(JsonReader reader){
// TODO自动生成的方法存根
Log.e(TAG,inidde readgson+读者);

尝试{
Log.e(TAG,inside try);
reader.beginObject();
Log.e(123,inside try); (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自动生成的catch块
Log.e(TAG,catch);
e.printStackTrace();
}
}

输出:

  01-28 10:20:53.519:E / TAG(420):状态码----------- 200 
01 -28 10:20:53.679:E / TAG(420):inidde readgsonJsonReader在第1行第1列
01-28 10:20:53.679:E / TAG(420):inside try
01- 28 10:20:53.679:E / TAG(420):内部捕获
01-28 10:20:53.679:W / System.err(420):java.io.EOFException:第1行输入结束列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):在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):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):在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):在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 )

预先致谢

解决方案

您正在以错误的方式使用内容流。查看标记的行:

  InputStream content = entity.getContent(); 

//(1)
BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
字符串行; ((line = bReader.readLine())!= null){
builder.append(line);
while
}

//(2)
JsonReader reader = new JsonReader(new InputStreamReader(content));
reader.setLenient(true);
readGson(reader);

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




  • 第一次换行之后,您将通过流来收集行并将它们连接在构建器中。您必须意识到, bReader 实际上仅仅是内容流的包装。因此,当您收集这些行时,会从 content 流中的内容被吃掉。因此,当(line = ...)!= null 时, false content stream在输入结束。
  • 然后你再次包装 content 流 - 解析JSON内容。但是流已经在这里输入的结尾,所以JSON阅读器没有任何东西需要消费。这就是该行的含义: java.io.EOFException:异常的第1行第1列处的输入结束。


你必须做的只是读取内容一次。所以,你有几个选择:


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

      HttpEntity entity = response.getEntity(); 

    //所有工作都在这里完成:)
    String jsonContent = EntityUtils.toString(entity);

    //从字符串创建读取器
    读取器stringReader = new StringReader(jsonContent);

    //将字符串读取器传递给JsonReader构造函数
    JsonReader reader = new JsonReader(stringReader);
    reader.setLenient(true);
    readGson(reader);

    ...
    //在方法结尾返回JSON响应
    return jsonContent;



I am doing a api call and in response i am getting json. So for that I want to parse it directly through input stream so that there would not be need of storing it in memory. For this I am trying to use JSONReader but that i am unable use for api's less than 11. So i dont know how to proceed with. I want it to be done from 2.0 version onwards. Even parsing through JsonReader is not working. I was thing of having GSON parser but i am not getting how to implement the same with Inputstream.

EDIT: My code for the same:

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

output:

    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)

Thanks in advance.

解决方案

You're using the content stream in a wrong way. Look at the marked lines:

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

The issue here is that you wrap the same stream twice (on marked line).

  • After first wrap, you go through the stream collecting the lines and concatenating them in a builder. You must be aware that effectively the bReader is just a wrapper around the content stream. So while you are collecting the lines, the content from the content stream is eaten. So, the condition (line = ...) != null is false when the content stream is at the end of input.
  • Then you wrap the content stream again - for parsing JSON contents. But the stream is already at the end of input here, so there is nothing to consume by the JSON reader. And that exactly is the meaning of the line: java.io.EOFException: End of input at line 1 column 1 of your exception.

What you have to do is to read through the content stream only once. So, you have several options here:

  • Don't save received contents to a String. You delete the first wrap and the loop which builds the response string using a builder. If that's not an option then I recommend:
  • Save the whole response to a String. Note: you can use the EntityUtils class for this since it will do the work for you:

    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;
    

这篇关于直接使用输入流解析json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆