1

Jackson JSON parserを使用して JSON 文字列を解析したい。解析したい JSON コードには、オブジェクトがある配列が含まれています。textこのオブジェクトから、およびretweet_count属性を抽出します。

[
    {
        "created_at": "Tue Jan 08 08:19:58 +0000 2013",
        "id": 288560667345178600,
        "text": "test tweet",
        "source": "web",
        "truncated": false,
        "user": {
            "id": 941802900,
            "id_str": "941802900",
            "location": ""
        },
        "contributors": null,
        "retweet_count": 0,
        "favorited": false,
        "retweeted": false
    }
]

私はこのコードを使用してそれをやろうとしました:

JsonFactory f = new JsonFactory();
JsonParser jp = f.createJsonParser(str);

boolean first = true;

while (jp.nextValue() != JsonToken.END_ARRAY) {
    Tweet tweet = new Tweet();
    while (jp.nextToken() != JsonToken.END_OBJECT) {
        String fieldName = jp.getCurrentName();
        jp.nextToken();

            if (fieldName.equals("text")) {
            tweet.setText(jp.getText());
        } else if (fieldName.equals("retweet_count")) {
            tweet.setRetweetCount(jp.getValueAsLong());
        }
    }
}

ただし、期待した結果が得られません。問題は、「ツイート」オブジェクト内に別の「ユーザー」オブジェクトがあり、パーサーがユーザー オブジェクトの に遭遇すると、それがツイート オブジェクト全体}の であると考えることにあると思います。}この状況を解決する方法を教えてください。

4

3 に答える 3

1

ツリー モデルやデータ バインディングの代わりにストリーミング API を使用しようとする特定の理由はありますか? 後者の 2 つは、はるかに単純なコードになる可能性があります。例えば:

@JsonIgnoreProperties(ignoreUnknown=true) // so we only include ones we care about
public class Tweet {
    String text;
    int retweet_count;
}

ObjectMapper mapper = new ObjectMapper(); // reusable (please reuse, expensive to create)
Tweet tweet = mapper.readValue(json, Tweet.class);

System.out.println("Tweet with text '"+tweet.text+"', retweet count of "+tweet.retweet_count);

データバインディング付き。そしてツリーモデルでは:

ObjectNode root = mapper.readTree(json);
String text = root.path("text").getText();
// and so on
于 2013-01-09T18:56:19.370 に答える
0

これが機能する更新されたコードです。userfieldNameを考慮して個別に解析する必要があるため、}ユーザー オブジェクトの はルート オブジェクトの最後とは見なされません。

while (jp.nextValue() != JsonToken.END_ARRAY) {
    Tweet tweet = new Tweet();
    while (jp.nextToken() != JsonToken.END_OBJECT) {
        String fieldName = jp.getCurrentName();
        jp.nextToken();

        if (fieldName.equals("user")) {
            //Here the current token in BEGIN_OBJECT
            while (jp.nextToken() != JsonToken.END_OBJECT) {
              //You can use the user properties here
            }
        } else if (fieldName.equals("text")) {
            tweet.setText(jp.getText());
        } else if (fieldName.equals("retweet_count")) {
            tweet.setRetweetCount(jp.getValueAsLong());
        }
    }
}
于 2013-08-10T16:56:57.947 に答える
0

おそらく、StaxMan が提案したことを実行し、オブジェクトでデータを正しくモデル化する必要がありますが、必要なデータを取得するための最速の方法は、以下のコード サンプルのようなものです。

List<Map<String, Object>> val = readValue(json, new TypeReference<List<Map<String, Object>>>() { });
for (Map<String, Object>> map : val) {
  String tweet = map.get("text");
  Integer retweetCount = map.get("retweet_count");
}   
于 2013-01-13T14:35:17.137 に答える