java程序员app_Google App Engine上的Java Facebook应用程序

Facebook于2004年2月启动,是世界上最大的社交网络,有超过9亿用户使用该网站与其亲朋好友共享内容。 2007年5月启动的Facebook平台使第三方能够编写与Facebook集成的应用程序。 该平台最初支持多种编程语言(包括Java),但现在仅提供JavaScript和PHP的本机SDK(以及对iOS和Android设备上的应用程序的支持)。 然而,开源RestFB项目已保持了Java API,因为Facebook的停产(见相关主题 )。

Google App Engine(GAE)是平台即服务(PaaS),可让注册的开发人员在Google的基础架构上运行用Python,Java或Go编写的应用程序。 本文向您展示如何注册Facebook应用程序,使用Java开发它以及如何在GAE上免费部署它以供任何已登录的Facebook用户使用。 (请注意,Google每天对GAE上部署的每个应用程序可以使用的资源施加限制。)

您将创建的简单应用程序列出用户的所有朋友及其ID和个人资料图片-类似于Facebook用户个人资料上朋友页面的先前外观。 要开发该应用程序,您需要:

  • 一个Facebook帐户
  • Google帐号
  • 装有GAE插件的Eclipse IDE(请参阅参考资料
  • 熟悉使用Eclipse

该应用程序的示例代码也可以下载

注册申请

第一步是在Facebook和GAE上注册您的应用程序。 最好在两个平台上同时创建应用程序,以确保输入的信息根据需要匹配。

注册一个Facebook应用程序

登录Facebook并通过https://developers.Facebook.com/apps启动开发人员应用程序。 (如果是第一次启动它,则必须授予该应用程序对您的个人资料的访问权限才能继续。)

单击“应用程序”页面右上方的“创建新应用程序”以显示“创建新应用程序”对话框,如图1所示:

图1. Facebook Create New App对话框
Facebook“创建新应用”对话框的屏幕截图

输入应用程序的有效名称和可用名称空间。 名称空间是在Facebook应用程序URL中使用的单字唯一标识符。 (在图1中 ,我输入My Old Friends作为应用程序名称, myoldfriends作为名称空间。)取消选择Heroku提供的免费托管选项,然后单击Continue 。 在下一个对话框中键入CAPTCHA代码,然后单击Submit弹出新应用程序的基本设置对话框,如图2所示:

图2. Facebook应用程序基本设置对话框
Facebook应用程序基本设置对话框的屏幕截图

请注意屏幕顶部的App ID和App Secret键(在图2中隐藏)。 Facebook使用它们来识别您的应用程序。 将它们保密,不允许其他开发人员使用它们,因为在您不知情的情况下,它们可能会被恶意使用。

在“ 应用程序域”字段中输入应用程序域 。 这必须是您要在GAE开发人员网站上为该应用程序注册的GAE域,因此它必须以.appspot.com结尾。 例如,在图2中 ,我输入了myoldfacebookfriends.appspot.com 。 由于该域不再可用,因此您必须使用其他域。 只要确保它与您注册GAE应用程序时使用的应用程序标识符匹配即可。

在“选择应用程序与Facebook的集成方式”下,选择“ 具有Facebook登录名的网站”,然后输入由您在“ 应用程序域”字段中输入的GAE域组成的站点URL,并以http:// 。 (在图2中 ,我输入了http://myoldfacebookfriends.appspot.com 。)

选择Facebook上的App,然后输入将在其中运行应用程序的servlet的画布URL。 对于此应用程序,画布URL以一个问号结尾,以指示该应用程序的参数将通过发送到该应用程序的请求URL传递。 除了https替换http之外,安全画布URL与画布URL相同。 同样,URL末尾的问号很重要。 (我的应用程序servlet的URL是http://myoldfacebookfriends.appspot.com/myoldfacebookfriends,因此在图2中 ,我输入了http://myoldfacebookfriends.appspot.com/myoldfacebookfriends?作为画布URL和https://myoldfacebookfriends.appspot.com/myoldfacebookfriends?作为安全画布URL。)

这是在Facebook上设置应用程序所需要做的全部工作,但最好配置一些其他设置(例如,应用程序的图标及其类别),以修改将应用程序呈现给用户的方式。

向GAE注册应用程序

现在该应用程序已在Facebook中注册,接下来您将在GAE中注册它。

在GAE的应用程序页面(https://appengine.google.com/)上登录,然后点击创建应用程序 。 在“应用程序标识符”下,输入您在Facebook应用程序基本设置中使用的相同应用程序域名。 (为您提供了appspot.com部分。)您可以根据需要使用任何名称作为应用程序标题,该名称用于搜索已注册的应用程序。 将其余选项保留为默认值。

图3. GAE的“创建应用程序”对话框
GAE的“创建应用程序”对话框的屏幕截图

单击创建应用程序以完成GAE注册过程。

开发应用程序

在Eclipse中,通过单击文件>新建> Web应用程序项目 ,或在Google服务和部署工具菜单下的新建Web应用程序项目按钮创建一个新的GAE项目。 输入项目名称和程序包名称。 取消选择使用Google Web Toolkit 。 下载RestFB JAR文件(请参阅相关信息 ),并将其添加到项目的WEB-INF / lib文件夹。

将应用程序的Servlet定义添加到项目的web.xml文件中。 清单1显示了我使用的定义:

清单1. Servlet定义
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>myoldFacebookfriendsServlet</servlet-name>
<servlet-class>com.Facebook.friends.MyOldFacebookFriendsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myoldFacebookfriendsServlet</servlet-name>
<url-pattern>/myoldFacebookfriends</url-pattern>
</servlet-mapping>
</web-app>

请注意, <url-pattern>与Facebook应用程序基本设置对话框中的画布URL中的相同,但没有问号。

自2011年10月起,Facebook应用程序要求启用安全套接字层(SSL); 在GAE上默认为禁用。 要启用它,请将以下行添加到appengine-web.xml中:

<ssl-enabled>true</ssl-enabled>

Facebook签名请求

Facebook使用HTTP POST方法将已签名的请求发送到应用程序servlet,以创建应用程序的内容。 该请求包含64位编码的有效负载,其中包含元数据以及当前用户应用程序的OAuth令牌。 仅当用户已授予应用程序对其个人资料的访问权限时,这才包括在请求的有效负载中。 您需要将其转换为Java对象,以便应用程序可以使用它。

清单2显示了签名请求的Java对象的源。 为了清楚起见,我省略了所有适当的get和set方法。 它们包含在源代码下载中(请参阅下载 )。

清单2.带签名的请求对象
import org.apache.commons.codec.binary.Base64;
import org.codehaus.jackson.map.ObjectMapper;

public class FacebookSignedRequest {

   private String algorithm;
   private Long expires;
   private Long issued_at;
   private String oauth_token;
   private Long user_id;
   private FacebookSignedRequestUser user;

   public static class FacebookSignedRequestUser {

      private String country;
      private String locale;
      private FacebookSignedRequestUserAge age;

      public static class FacebookSignedRequestUserAge {
         private int min;
         private int max;

      }
      
   }
   
}

您可以使用Apache Commons Codec库中的Base64解码有效负载。 解码后的有效负载采用JavaScript对象表示法(JSON),可以使用Jackson JSON处理器将其转换为Java对象。 下载其JAR文件并将其添加到项目中(请参阅参考资料 )。 将清单3中所示的静态帮助器方法添加到FacebookSignedRequest类中以创建对象:

清单3.用于编码和解码有效负载的Helper方法
public static FacebookSignedRequest getSignedRequest(String signedRequest) 
      throws Exception {
   
   String payload = signedRequest.split("[.]", 2)[1];
   payload = payload.replace("-", "+").replace("_", "/").trim();
   String jsonString = new String(Base64.decodeBase64(payload.getBytes()));
   return new ObjectMapper().readValue(jsonString, 
                              FacebookSignedRequest.class);
   
}

创建servlet

现在,您可以开始编码将在servlet中运行的应用程序。 创建一个新类,其签名与web.xml中的<servlet-class>定义相同。 首先,您需要使用SignedRequest类从有效负载中提取OAuth令牌,如清单4所示:

清单4.提取OAuth令牌
String signedRequest = (String) request.getParameter("signed_request");
FacebookSignedRequest FacebookSR = null;
try {
   FacebookSR = FacebookSignedRequest.getSignedRequest(signedRequest);
} catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
}
String oauthToken = FacebookSR.getOauth_token();

如果oauthToken对象为null,则用户尚未授予对应用程序的访问权限,必须将其重定向到身份验证URL。 所有应用程序中的标准URL格式如下:

https://www.Facebook.com/dialog/oauth?client_id=API KEY&redirect_uri=
   https://apps.Facebook.com/Application Namespace/&scope=Permissions

身份验证URL中的API KEYApplication Namespace是该Application Namespace的Facebook基本设置对话框中显示的API KEYPermissions是您的应用程序所需的权限列表。 默认情况下,所有应用程序都具有基本权限,您无需为本文的目的添加任何其他权限。 (请参阅相关主题的链接,获得许可的完整列表。)

您可以在Facebook开发人员应用程序的“设置”>“身份验证对话框”页面中自定义此页面的外观。 通常,您将使用Servlet HttpServletRequest.sendRedirect()方法,但是由于该应用程序将在apps.Facebook.com域的<iframe>运行,因此清单5所示的简短JavaScript代码段更改了Javascript的位置。浏览器窗口中的应用程序URL:

清单5.引用到应用程序URLJavaScript代码
PrintWriter writer = response.getWriter();
if(oauthToken == null) {
   
     response.setContentType("text/html");
     String authURL = "https://www.Facebook.com/dialog/oauth?client_id="
       + API_KEY
       + "&redirect_uri=https://apps.Facebook.com/myoldfriends/&scope=";
     writer.print("<script> top.location.href='" + authURL + "'</script>");
     writer.close();

}

使用有效的OAuth令牌,您可以从RestFB库创建DefaultFacebookClient ,并使用它通过fetchConnection()调用从Facebook的Graph API中检索数据。 在https://developers.Facebook.com/tools/explorer上访问Facebook上的Graph Explorer。 从右上角的下拉框中选择您正在开发的应用程序,然后单击“ 获取访问令牌”以授予访问权限。 单击“连接”标题下的各种链接以查看结果。

要获取用户的朋友,请单击“ 朋友”链接并查看结果。 请注意,资源管理器中URL的值为user id /friends 。 函数调用中的连接参数通常将使用与“图形资源管理器”中相同的值。 但是,由于该应用程序使用已登录用户的数据,因此您可以用me替换用户ID,从而使值成为me/friends 。 该调用返回原始Connection类型,并且由于类类型为User ,您需要将其添加为参数。 最后的电话是:

Connection<User> myFriends = FacebookClient.fetchConnection("me/friends", User.class);

所述的结果fetchConnection()方法调用以保持ListList中的对象Connection类。 的Connection类实现Iterable接口,这样就可以得到各List中的对象List通过使用增强的for循环:

for (List<User> myFriendsList : myFriends)

在循环的每次迭代中, myFriendsList对象都包含该返回数据页的当前用户列表。 此列表中的每个User对象用于在Servlet将创建的用户表中创建一行。 尽管可以从User对象中检索用户ID和名称,但个人资料图片不能。 但是,Facebook提供了一个用于检索任何用户的个人资料图片的URL:https://graph.facebook.com/ 用户ID / picture。 因此,通过将URL中的用户ID替换为来自User对象的用户ID来创建个人资料图片的URL。 使用与以前相同的PrintWriter对象,将带有标题行的表写入画布:

writer.print("<table><tr><th>Photo</th><th>Name</th><th>Id</th></tr>");

如上所述,遍历User对象的列表,然后使用每个User对象的实例变量为此表写一个新行:

for (List<User> myFriendsList : myFriends) {

   for(User user: myFriendsList)
      writer.print("<tr><td>" + 
         "<img src=\"https://graph.facebook.com/" + user.getId() + "/picture\"/>" +
         "</td><td>" + user.getName() +"</td><td>" + user.getId() + "</td></tr>");

}

最后,关闭<table>标记,并关闭PrintWriter对象以完成servlet:

writer.print("</table>");
writer.close();

清单7显示了最终的servlet doPost()方法:

清单7. doPost()方法
public void doPost(HttpServletRequest request, HttpServletResponse response) 
  throws ServletException, IOException {
  
  String signedRequest = (String) request.getParameter("signed_request");
  FacebookSignedRequest facebookSR = null;
  try {
    facebookSR = FacebookSignedRequest.getSignedRequest(signedRequest);
  } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  String oauthToken = facebookSR.getOauth_token();
  PrintWriter writer = response.getWriter();
  if(oauthToken == null) {
    
    response.setContentType("text/html");
    String authURL = "https://www.facebook.com/dialog/oauth?client_id="
      + Constants.API_KEY + 
      "&redirect_uri=https://apps.facebook.com/myoldfriends/&scope=";
    writer.print("<script> top.location.href='"  + authURL + "'</script>");
    writer.close();

  }
  else {
    
    FacebookClient facebookClient = new DefaultFacebookClient(oauthToken);
    Connection<User> myFriends = facebookClient.fetchConnection("me/friends", 
                                                User.class);
    writer.print("<table><tr><th>Photo</th><th>Name</th><th>Id</th></tr>");
    for (List<User> myFriendsList : myFriends) {

      for(User user: myFriendsList)
        writer.print("<tr><td><img src=\"https://graph.facebook.com/" + 
                 user.getId() + "/picture\"/></td><td>" + user.getName() +
                 "</td><td>" + user.getId() + "</td></tr>");

    }
    writer.print("</table>");
    writer.close();
    
  }

}

部署应用程序

创建了Servlet之后,就可以部署应用程序了。 点击Eclipse中的Google图标,然后选择部署到App Engine 。 将应用程序编译并上传到服务器后,您(和任何其他Facebook用户)可以通过http://apps.facebook.com/APP ID /在Facebook中安装该应用程序,然后查看结果。

结论

本文演示了如何在Java上注册,实现和部署Google应用程序服务上托管的Facebook应用程序。 现在您已经熟悉了基础知识,建议您尝试一些变体。

您可以通过使用对JavaServer Pages(JSP)页面的标准RequestDispatcher.forward()调用来实现更传统的Model-View-Controller(MVC)方法,而不是将内容HTML直接编写到页面中。

您可以尝试创建一个对Graph API提供的数据使用某些额外权限的应用程序。 通过将每个请求添加到scope请求参数,将应用程序所需的权限列表传递给身份验证URL。 RestFB提供了一个辅助方法StringUtils.join()来正确创建列表。 它使用单个String数组作为参数; 数组中的每个条目都是一个权限名称。

最后,你可以尝试重新使用Facebook-Java的API谷歌代码项目的示例应用程序-替代实现Facebook的API的-而不是RestFB(参见相关主题 )。


翻译自: https://www.ibm.com/developerworks/java/library/j-fb-gae/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值