有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

跳过使用Jackson值的java JSON解析

我正试图解析一个来自Facebook的请求的提要。然而,我的解析器跳过了很多信息。下面是代码的一部分,一个示例说明了正在解析的内容以及if语句中打印的内容。例如,找不到“消息”。想法

List<FacebookItem> list = new ArrayList<FacebookItem>();

try {
    if (jFactory == null)
        jFactory = new JsonFactory();

    jParser = jFactory.createJsonParser(json);

    FacebookItem o = null;
    while (jParser.nextToken() != null) {
        if ("type".equals(jParser.getCurrentName())) {
            jParser.nextToken();
            o = new FacebookItem();
            o.setType(jParser.getText());
            System.out.println("Found type:   " + jParser.getText());
        }
        if ("from".equals(jParser.getCurrentName()))
            while (!"name".equals(jParser.getCurrentName())) {
                jParser.nextToken();
            }
            jParser.nextToken();
            o.getUser().setUserName(jParser.getText());
            System.out.println("Found name:   " + jParser.getText());
        }
        if ("message".equals(jParser.getCurrentName())) {
            jParser.nextToken();
            o.setText(jParser.getText());
            System.out.println("Found message:   " + jParser.getText());
        }
        if ("created_time".equals(jParser.getCurrentName())) {
            jParser.nextToken();
            o.setTimestamp(jParser.getText());
            System.out.println("Found created_time:   " + jParser.getText());
            list.add(o);
        }
    }
    jParser.close();

} catch (JsonGenerationException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

{"data":[{"type":"photo","link":"http://www.facebook.com/photo.php?fbid=10151331660204305&set=a.299455459304.180838.197394889304&type=1&relevant_count=1","from":{"name":"FC Barcelona","category":"Professional sports team","id":"197394889304"},"message":"Puyol faces eight week layoff http://bit.ly/QXhOFE\r\n\r\nPuyol, vuit setmanes de baixa http://bit.ly/T1enma\r\n\r\nPuyol, ocho semanas de baja http://bit.ly/T0eaj8","picture":"http://photos-g.ak.fbcdn.net/hphotos-ak-snc6/246623_10151331660204305_75156416_s.jpg","created_time":"2012-10-03T17:40:06+0000","id":"197394889304_10151331937599305"},{"type":"checkin","link":"http://www.facebook.com/pages/Hubben-21/249474758405147","from":{"name":"Andreas Rol\u00e9n","id":"575703056"},"message":"En timme in i turneringen och redan chipleader","picture":"http://profile.ak.fbcdn.net/static-ak/rsrc.php/v2/y5/r/j258ei8TIHu.png","name":"Hubben 2.1","created_time":"2012-10-03T17:24:19+0000","id":"575703056_10151181582028057"},{"type":"photo","link":"http://www.facebook.com/photo.php?fbid=10151445544542786&set=at.10151445533587786.588547.694032785.688088336&type=1&relevant_count=1","from":{"name":"Jens Wilhelmsson","id":"688088336"},"picture":"http://photos-h.ak.fbcdn.net/hphotos-ak-prn1/72091_10151445544542786_676020840_s.jpg","created_time":"2012-10-03T17:21:40+0000","id":"688088336_10151111148358337"},{"type":"link","from":{"name":"Eric Lindqvist","id":"648057222"},"created_time":"2012-10-03T17:20:52+0000","id":"648057222_10151249963167223"}

Found type:   photo
Found name:   FC Barcelona
Found name:   Andreas Rolén
Found name:   Hubben 2.1
Found created_time:   2012-10-03T17:24:19+0000
Found type:   photo
Found name:   Jens Wilhelmsson
Found name:   Eric Lindqvist

共 (3) 个答案

  1. # 1 楼答案

    我真的不知道你的JSON库,但是Android提供了一个nice JSON API in the SDK itself,为什么不使用它呢

    JSONArray data = new JSONArray(jsonString);
    int itemCount = data.length();
    List<MyObject> list = new ArrayList<MyObject>(itemCount);
    
    for (int i=0; i<itemCount; ++i) {
      JSONObject item = data.getJSONObject(i);
    
      String name = item.getString("name");
      String message = item.optString("message");
    
      MyObject o = new MyObject(name, message);
      list.add(o);
    }
    

    最好是将单个项目的JSON解析封装到MyObject类中:

    JSONArray data = new JSONArray(jsonString);
    int itemCount = data.length();
    List<MyObject> list = new ArrayList<MyObject>(itemCount);
    
    for (int i=0; i<itemCount; ++i) {
      JSONObject item = data.getJSONObject(i);
    
      MyObject o = new MyObject();
      o.setFromJSON(item);
      list.add(o);
    }
    
  2. # 2 楼答案

    首先-JSON字符串不完整-最后缺少]}。当我附加它时,我的costom构建的JSON解析器会得到以下结果:

      data:
        id=197394889304_10151331937599305
        picture=http://photos-g.ak.fbcdn.net/hphotos-ak-snc6/246623_10151331660204305_75156416_s.jpg
        message=Puyol faces eight week layoff http://bit.ly/QXhOFE\r\n\r\nPuyol, vuit setmanes de baixa http://bit.ly/T1enma\r\n\r\nPuyol, ocho semanas de baja http://bit.ly/T0eaj8
        link=http://www.facebook.com/photo.php?fbid=10151331660204305&set=a.299455459304.180838.197394889304&type=1&relevant_count=1
        from:
          id=197394889304
          category=Professional sports team
          name=FC Barcelona
        created_time=2012-10-03T17:40:06+0000
        type=photo
        id=575703056_10151181582028057
        picture=http://profile.ak.fbcdn.net/static-ak/rsrc.php/v2/y5/r/j258ei8TIHu.png
        message=En timme in i turneringen och redan chipleader
        name=Hubben 2.1
        link=http://www.facebook.com/pages/Hubben-21/249474758405147
        from:
          id=575703056
          name=Andreas Rol\u00e9n
        created_time=2012-10-03T17:24:19+0000
        type=checkin
        id=688088336_10151111148358337
        picture=http://photos-h.ak.fbcdn.net/hphotos-ak-prn1/72091_10151445544542786_676020840_s.jpg
        link=http://www.facebook.com/photo.php?fbid=10151445544542786&set=at.10151445533587786.588547.694032785.688088336&type=1&relevant_count=1
        from:
          id=688088336
          name=Jens Wilhelmsson
        created_time=2012-10-03T17:21:40+0000
        type=photo
        id=648057222_10151249963167223
        from:
          id=648057222
          name=Eric Lindqvist
        created_time=2012-10-03T17:20:52+0000
        type=link
    

    我现在的问题是——这里一切都好吗?有错误吗

  3. # 3 楼答案

    我真的很喜欢杰克逊,他速度快,能力强。我从未使用过流式API(您在这里使用的),但它看起来确实很难。除非您非常担心内存使用,否则我建议您不要使用流式API。因为你在移动设备上,显然对资源有更多的关注,所以这就是你的决定

    如果决定放弃流式API,最简单的方法是创建映射到JSON的java对象模型,然后使用ObjectMapper将字符串读入该对象模型。您可以使用注释为映射或其他内容重命名字段,自定义转换。下面这样的方法应该可以使用(取决于FacebookItem的真正定义)

      import org.codehaus.jackson.map.DeserializationConfig.Feature;
      ....
      ObjectMapper mapper = new ObjectMapper();
      // tell it to not fail on properties that you don't have mapped, that way you
      // only have to map the fields you are interested in and can ignore the rest
      mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
      ItemContainer itemContainer = mapper.readValue(facebookDataJsonString, ItemContainer.class);
    
      // where elsewhere you have defined something like:
    
      class ItemContainer {
        List<FacebookItem> data;
        // getters and setters for data.
      }
    

    以下是eugen在评论中指定的选项。如果您的JSON包含一个列表(即没有“数据”包装器,而是看起来像[{...},{...}]),这将起作用:

      ObjectMapper mapper = new ObjectMapper();
      // tell it to not fail on properties that you don't have mapped, that way you
      // only have to map the fields you are interested in and can ignore the rest
      mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
      List<FacebookItem> items = mapper.readValue(jsonString, new TypeReference<List<Stuff>>(){});
    

    最后,第三种选择是,如果没有对象映射,只需将其读入映射即可。那么至少你不必处理JSONObject和JSONArray之类的东西

      ObjectMapper mapper = new ObjectMapper();
      Map<String, Object> container = mapper.readValue(facebookDataJsonString, Map.class);
      List<Map<String,Object>> = container.get("data");
      for (Map<String,Object> map : container ) {
        System.out.println( "type is " + map.get("type"));
        System.out.println( "from is " + ((Map<String,Object>)map.get("from")).get("name"));
        System.out.println( "message is " + map.get("message"));
      }