我有一个桌面应用程序,它读取 Facebook 消息(FQL 术语中的 unified_message),它由其他用户留在我的 Facebook 页面上。问题是:当用户编写包含链接的消息时,Facebook 会自动将一些对象附加到消息中。这个附件在 RestFb Lib 中导致异常。不幸的是,我的页面访问令牌无济于事,因为您必须在 Facebook 中以我的身份登录才能使用它。但场景很简单,尝试在“www.wheather.com - 酷网站”之类的页面上留言。我已经用 RestFb 1.6.9 和 1.6.11 进行了尝试——两者的结果相同。抱歉格式化。我不能以其他方式做到这一点:(
这是 1.6.11 的堆栈:
com.restfb.exception.FacebookJsonMappingException: Unable to convert Facebook response JSON to a list of java.lang.String instances. Offending JSON is {"38d79791ef0dac6f0b645a87f4d152d7":{"icon":"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif","fb_object_type":"","tagged_ids":[],"description":"The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.","name":"National and Local Weather Forecast, Hurricane, Radar and Report","fb_object_id":"","caption":"www.weather.com","properties":[],"media":[],"href":"http://www.weather.com/"}}
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:171)
at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:653)
at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:290)
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:181)
at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:653)
at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:290)
at myprogram.MyDefaultFacebokClient.executeMultiquery(MyDefaultFacebokClient.java:62)
Caused by: com.restfb.json.JsonException: JsonObject["data"] not found.
at com.restfb.json.JsonObject.get(JsonObject.java:525)
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:155)
... 17 more
这是 1.6.9 的堆栈:
com.restfb.exception.FacebookJsonMappingException: Unable to convert Facebook response JSON to a list of java.lang.String instances. Offending JSON is {"38d79791ef0dac6f0b645a87f4d152d7":{"icon":"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif","fb_object_type":"","tagged_ids":[],"description":"The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.","name":"National and Local Weather Forecast, Hurricane, Radar and Report","fb_object_id":"","caption":"www.weather.com","properties":[],"media":[],"href":"http://www.weather.com/"}}
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:167)
at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:602)
at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:279)
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:177)
at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:602)
at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:279)
at myprogram.MyDefaultFacebokClient.executeMultiquery(MyDefaultFacebokClient.java:62)
. . .
Caused by: com.restfb.json.JsonException: JsonObject["data"] not found.
at com.restfb.json.JsonObject.get(JsonObject.java:525)
at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:151)
... 17 more
这是 FQL 请求:
{
"users":"SELECT uid,first_name,middle_name,last_name,name,pic_small,pic_big,profile_update_time,timezone,religion,birthday,birthday_date,sex,hometown_location,relationship_status,political,current_location,about_me,notes_count,wall_count,status,locale,profile_url,verified,profile_blurb,username,is_blocked,email,friend_count,languages FROM user WHERE uid IN (SELECT sender FROM #messages)"
,"msg":"SELECT message_id FROM unified_message WHERE thread_id='t_id.238275946308607' AND timestamp > '1360112817564' AND sender.user_id != '507447822604742' LIMIT 100"
,"messages":"SELECT message_id,thread_id,subject,body,unread,action_id,timestamp,tags,sender,recipients,object_sender,html_body,attachments,shares,share_map FROM unified_message WHERE message_id IN (SELECT message_id FROM #msg) AND timestamp > '1360112817564' AND timestamp <= '1360117314920' LIMIT 100"
}
以下是 Facebook Explorer 对上述请求的回复:
{
"data": [
{
"name": "msg",
"fql_result_set": [
{
"message_id": "m_mid.1360112949050:d17ca4ed7fc6236a75"
}
]
},
{
"name": "messages",
"fql_result_set": [
{
"message_id": "m_mid.1360112949050:d17ca4ed7fc6236a75",
"thread_id": "t_id.238275946308607",
"subject": null,
"body": "Have a look on http://www.weather.com 1",
"unread": true,
"action_id": "1360112949128000000",
"timestamp": "1360112949058",
"tags": [
"inbox",
"source:web"
],
"sender": {
"name": "Adam Client",
"email": "100004967623158@facebook.com",
"user_id": "100004967623158"
},
"recipients": [
{
"name": "MB Aerospace Corp.",
"email": "507447822604742@facebook.com",
"user_id": "507447822604742"
},
{
"name": "Adam Client",
"email": "100004967623158@facebook.com",
"user_id": "100004967623158"
}
],
"object_sender": null,
"html_body": "Have a look on http://www.weather.com 1",
"attachments": [
],
"shares": [
"38d79791ef0dac6f0b645a87f4d152d7"
],
"share_map": {
"38d79791ef0dac6f0b645a87f4d152d7": {
"media": [
],
"name": "National and Local Weather Forecast, Hurricane, Radar and Report",
"href": "http://www.weather.com/",
"caption": "www.weather.com",
"description": "The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.",
"properties": [
],
"fb_object_type": "",
"fb_object_id": "",
"icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
"tagged_ids": [
]
}
}
}
]
},
{
"name": "users",
"fql_result_set": [
{
"uid": 100004967623158,
"first_name": "Adam",
"middle_name": "",
"last_name": "Client",
"name": "Adam Client",
"pic_small": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/371585_100004967623158_2019810380_t.jpg",
"pic_big": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/371585_100004967623158_2019810380_n.jpg",
"profile_update_time": 1360108999,
"timezone": null,
"religion": null,
"birthday": null,
"birthday_date": null,
"sex": "male",
"hometown_location": null,
"relationship_status": null,
"political": null,
"current_location": null,
"about_me": null,
"notes_count": null,
"wall_count": null,
"status": null,
"locale": "en_US",
"profile_url": "https://www.facebook.com/adam.client.5",
"verified": null,
"profile_blurb": null,
"username": "adam.client.5",
"is_blocked": false,
"email": null,
"friend_count": 1,
"languages": [
]
}
]
}
]
}
最后一个。我使用重新定义的 FacebookClient。源代码取自这里,stackoverflow.com。我不记得确切的原因,但类似于 DefaultFacebookClient 无法正确映射来自 Facebook 的结果(消息的附件)。
public class MyDefaultFacebokClient extends DefaultFacebookClient {
@Override public <T> T executeMultiquery (Map<String, String> queries, Class<T> objectType, Parameter... parameters)
{
verifyParameterPresence("objectType", objectType);
for (Parameter parameter : parameters)
if (QUERY_PARAM_NAME.equals(parameter.name))
throw new IllegalArgumentException("You cannot specify the '" + QUERY_PARAM_NAME
+ "' URL parameter yourself - " + "RestFB will populate this for you with "
+ "the queries you passed to this method.");
try {
List<JsonObject> jsonObjects = jsonMapper.toJavaList(makeRequest("fql", false, false, null,
parametersWithAdditionalParameter(Parameter.with("q", queriesToJson(queries)), parameters)), JsonObject.class);
JsonObject normalizedJson = new JsonObject();
for (int i = 0; i < jsonObjects.size(); i++)
{
JsonObject jsonObject = jsonObjects.get(i);
// For empty result sets, Facebook will return an empty object instead of
// an empty list. Hack around that here.
JsonArray resultsArray =
jsonObject.get("fql_result_set") instanceof JsonArray ? jsonObject.getJsonArray("fql_result_set")
: new JsonArray();
normalizedJson.put(jsonObject.getString("name"), resultsArray);
}
return objectType.equals(JsonObject.class) ? (T) normalizedJson : jsonMapper.toJavaObject(normalizedJson.toString(), objectType);
} catch (JsonException e) {
throw new FacebookJsonMappingException("Unable to process fql.multiquery JSON response", e);
}
}
}
任何想法将不胜感激。