Facebook API学习获取FB用户信息

做的项目是SNS相关的,想从facebook上扒些用户数据下来,学习了下Facebook API和restfb项目(Representational State Transfer)。

Facebook官方文档:http://developers.facebook.com/


1.  使用JavaScript从Facebook获取用户数据。

首先加载JavaScript SDK
    

JavaScript SDK需要一个fb-root元素,并用FB.init初始化SDK。注意把YOUR_APP_ID替换为从Facebook获取的ID。

fb-root不能用display:nonevisibility:hidden来隐藏,否则在IE下可能工作不正常。fb-root也最好不要放在一个position:absoluteposition:relative的元素中(fb-root最好是放在靠近body开始处)。

SDK是异步加载的(js.async = true),而SDK的加载协议则是根据页面的加载协议而定,可以是HTTP或HTTPS(js.src = "//...")。

当SDK加载完毕后,就会调用window.fbAsyncInit,而FB.init必须在其他初始化代码之前被调用,源码如下: 

if(window.fbAsyncInit&&!window.fbAsyncInit.hasRun){
    window.fbAsyncInit.hasRun=true;
    fbAsyncInit();
}
Channel File 的作用是跨域访问, channel.html的内容可以仅仅是一行代码: 
对通道文件而言,尽可能长的让它缓存。可以设置 Expires来实现。如果没有适当的缓存,跨域访问则会非常慢。用PHP来写 channel.html则是: 

 

channelUrl是可选的,但建议填写,它可以解决3方面的问题:

  1. 如果没有channelUrl,社交化插件可能无法显示。
  2. 如果没有channelUrl,而页面又包含自播放的音视频流,用户则可能听到2个声音,缘故是页面在跨域访问时将自动加载一次页面。
  3. channelUrl可以防止服务器日志记录产生重复计数。

获取用户FB数据的JS代码:

/*
 * facebook相关JS
 */
FACEBOOK_COMMON = { 

	scope :  "user_website,friends_website,user_birthday,friends_birthday,user_hometown,friends_hometown,user_friends,public_profile,email,read_stream,user_photos,user_videos,publish_stream,user_education_history,friends_education_history,user_location,friends_location,user_work_history,friends_work_history",

	/*
		获取自己和自己的facebook好友函数,异步保存用户自己的FB信息和FB好友信息
		参数 
			needUpdate : 是否需要更新自己在好友手中的备份
			needConnect : 是否需要登录FB true or fasle
		返回object内的参数
			friendArr : facebook好友
			me : 我的信息
			response : 服务端返回的信息
	*/
	getFriends : function(callback, needUpdate, needConnect){
		var uid;
		var accessToken ;
		var expiresIn;
		// 需要强制登录(存当保前用户的FB信息)的情况,使用FB.login方法,如果当前用户没有登录FaceBook,会弹出一个小窗口让用户登录
		if(needConnect){
			FB.login(function(response){
				if(response.authResponse){
					uid = response.authResponse.userID; // 取得 FBID
					accessToken = response.authResponse.accessToken; // 取得 accessToken
					expiresIn = response.authResponse.expiresIn;
					FB.api('/me?locale=ja_JP', function(user) { // 获取用户自己的FACEBOOK信息
						if(user != null) { 
							user.head = "https://graph.facebook.com/" + uid + "/picture"; // 头像
							var name = user.name;
							var data = "OAuthUid="+uid+"&accessToken="+accessToken+"&expiresIn="+expiresIn+"&name="+name;
						    $.ajax({
							    type:"get",
							    url: "yourURL?"+data, // 需要替换成你的后台处理的URL(存当保前用户的FB信息)
								data: data,
								success:function(responseObj) {
									user.msg = responseObj.response;
									// 调用自身,获取FB好友信息
									FACEBOOK_COMMON.getFriends(callback, needUpdate, false);
								},
								error:function(responseObj){
									console.log(responseObj.response);
								}
							});
						}
					});
				}
			},{scope : FACEBOOK_COMMON.scope});
			return;
		}
		// 不需要强制登录的情况,使用FB.getLoginStatus方法,如果当前用户没有登录FaceBook,不会执行任何操作
		FB.getLoginStatus(function(response){
			if(response.status == 'connected'){
				FB.api('/me?locale=ja_JP', function(user) { 
					if(user == null || user == undefined){
						console.log("user is null !");
						return;
					}
					if(user.error){
						console.log(user.error.message);
						FACEBOOK_COMMON.getFriends(callback, needUpdate, true);
					}
					uid = user.id
					user.head = "https://graph.facebook.com/" + uid + "/picture";
					// 获取FB好友
					FACEBOOK_COMMON.sendFriendRequest(callback, user, needUpdate);
				});
			} else{
				FACEBOOK_COMMON.getFriends(callback, needUpdate, true);
			}
		});
	},
	
	/*
		获取该用户的所有FB好友信息
	*/
	sendFriendRequest : function(callback, me, needUpdate){
		FB.api({ method: 'friends.get' }, function(idArr) {
			var friendArr = new Array();
			var returnData = new Object();
			if(idArr.length == 0){
				returnData.response = "no friend!";
				callback(returnData);
				return;
			}
			for(var i=0;iimport org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
// ...
	HttpClient httpClient = new HttpClient();
	httpClient.getParams().setParameter("http.protocol.content-charset","UTF-8");
	String url = "https://graph.facebook.com/me?";
	GetMethod getMethod = new GetMethod(url);
	NameValuePair[] accessData = { new NameValuePair("access_token",accessToken) };

	getMethod.setQueryString(accessData);
	try {
		httpClient.executeMethod(getMethod);
		byte[] responseBody = getMethod.getResponseBody();
		String responseStr = new String(responseBody, "utf-8");
		if(StringUtils.isEmpty(responseStr)) {
			System.out.println(responseStr);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
// ...


3.  使用第三方开源库restfb(http://restfb.com/),restfb1.6.16版支持Facebook API 2.1版本。

使用Maven的话,把下面代码加到项目的配置文件即可。或者下载jar包加到工程的类库(http://restfb.com/downloads/restfb-1.6.16.zip)

  com.restfb
  restfb
  1.6.16

代码:
package com.maitian.register.controllers.guide;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang.StringUtils;
import org.slf4j.bridge.SLF4JBridgeHandler;

import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.Parameter;
import com.restfb.exception.FacebookException;
import com.restfb.exception.FacebookGraphException;
import com.restfb.exception.FacebookJsonMappingException;
import com.restfb.exception.FacebookNetworkException;
import com.restfb.exception.FacebookOAuthException;
import com.restfb.exception.FacebookResponseStatusException;
import com.restfb.types.User;

public class RestFBTest {

	public static void main(String[] args) {
		SLF4JBridgeHandler.install();
		// 通过OAUTH认证获取
    	String accessToken = "CAAFeNg4fUMkBAOZBGwG26AzRVXJHb0ZA7ZCZAg83ATGytCHKNwZCt2jXY4BvqouLZCqc3ziMNtPGCQXpSK0GJZC5rGdZBknQOcCPrF9BWQ1qUSmmqAd75z9iMlpOXz4XjjWg7Y885XJB7IsoTxLKtwkcSNfWSqdd7GAkTqgFSS0jD39lrF4PnBQBQZCrcTABX7ilk306KhWURVgUSC4v1zVhf";
    	try {

    		// 方式一:直接调用API
    		HttpClient httpClient = new HttpClient();
    		httpClient.getParams().setParameter("http.protocol.content-charset","UTF-8");
    		// 获取用户FB信息
    		String url = "https://graph.facebook.com/me?";
    		GetMethod getMethod = new GetMethod(url);
    		NameValuePair[] accessData = { new NameValuePair("access_token",accessToken), new NameValuePair("locale","zh_CN") };

    		getMethod.setQueryString(accessData);
    		httpClient.executeMethod(getMethod);
    		byte[] responseBody = getMethod.getResponseBody();
    		String responseStr = new String(responseBody, "utf-8");
    		if(StringUtils.isNotEmpty(responseStr)) {
    			System.out.println(responseStr);
    		}

			System.out.println("=====================================");
			// 获取用户FB好友信息(只能取到名字和ID)
        	url = "https://graph.facebook.com/me/friends?";
        	getMethod = new GetMethod(url);
        	getMethod.setQueryString(accessData);

    		httpClient.executeMethod(getMethod);
    		responseBody = getMethod.getResponseBody();
    		responseStr = new String(responseBody, "utf-8");
    		if(StringUtils.isNotEmpty(responseStr)) {
    			System.out.println(responseStr);
    		}

			System.out.println("+++++++++++++++++++++++++++++++++++++");
    		// 方式二:使用restfb
    		FacebookClient facebookClient = new DefaultFacebookClient(accessToken);
    		User user = facebookClient.fetchObject("me", User.class, Parameter.with("locale", "zh_CN"));
    		System.out.println(user.getEmail());
    		System.out.println(user);

			System.out.println("=====================================");
			// (只能取到名字和ID)
    		Connection myFriends = facebookClient.fetchConnection("me/friends", User.class, Parameter.with("locale", "zh_CN"));
    		List fbids = new ArrayList();
    		for (User friend : myFriends.getData()) {
    			// 通过FBID去获取好友详细信息
    			user = facebookClient.fetchObject(friend.getId(), User.class);
        		System.out.println(user);
    			fbids.add(friend.getId());
    		}
    		// 一次返回所有好友信息,需要自己封装返回类型
    		// T = facebookClient.fetchObjects(fbids, Class objectType, Parameter.with("locale", "zh_CN"));
    		
    	} catch (FacebookJsonMappingException e) {
    		// Looks like this API method didn't really return a list of users
    		e.printStackTrace();
    	} catch (FacebookNetworkException e) {
    		// An error occurred at the network level  
    		int code = e.getHttpStatusCode();
    		System.out.println("API returned HTTP status code " + e.getHttpStatusCode());
    	} catch (FacebookOAuthException e) {  // Authentication failed - bad access token?  
    		e.printStackTrace();
    	} catch (FacebookGraphException e) {  // The Graph API returned a specific error 
    		e.printStackTrace(); 
    		System.out.println("Call failed. API says: " + e.getErrorMessage());
    		
    	} catch (FacebookResponseStatusException e) {  
    		// Old-style Facebook error response.  
    		// The Graph API only throws these when FQL calls fail.  
    		// You'll see this exception more if you use the Old REST API  
    		// via LegacyFacebookClient.  
    		if (e.getErrorCode() == 200) {
    			System.out.println("Permission denied!");
    		}
    	} catch (FacebookException e) {  
    		// This is the catchall handler for any kind of Facebook exception
    		e.printStackTrace();
    	} catch (Exception e) {
    		e.printStackTrace();
    	} finally {
    	    // Make sure to tear down when you're done using the bridge
    	    SLF4JBridgeHandler.uninstall();
    	}
    }
}




推荐去restfb(http://restfb.com/)官网看看,里面有很多的例子,还有Batch的处理(把多个请求命令合为一次请求)。
另外不推荐用FQL,估计在过一年Facebook就会废弃FQL了。


参考资料:
http://www.berlinix.com/web/facebook.php
restfb项目: http://restfb.com/
Facebook官方文档: http://developers.facebook.com/

你可能感兴趣的:(SNS)