我想使用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());
}
}
}
但是,我没有得到预期的结果。我认为问题是在'tweet'对象中,我有另一个'user'对象,当解析器遇到用户对象的}
时,它认为它是}
的整个推文对象。你能告诉我怎样才能解决这个问题?
答案 0 :(得分:1)
您是否有特殊原因尝试使用Streaming API而不是树模型或数据绑定?后两者可能会导致更简单的代码。例如:
@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
答案 1 :(得分: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");
}
答案 2 :(得分:0)
这是可以使用的更新代码。您需要考虑user
fieldName并单独解析它,因此用户对象的}
不会被视为根对象的结尾
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());
}
}
}