Java-приложения для Facebook на базе Google App Engine

Создание, реализация и установка приложения для Facebook в системе Google App Engine

Отсутствие поддержки Java™ на платформе Facebook не должно быть препятствием для создания приложений для Facebook на языке Java. Эта статья показывает, как создать приложение для Facebook, реализовать его на Java и установить в облаке Google App Engine.

Джозеф P. Маккарти, программист, IBM

Фотография Джозефа МаккартиДжозеф Маккарти (Joseph McCarthy) работает Java-программистом в лаборатории программного обеспечения Дублине. Пришел в IBM в июле 2002 года после окончания университета Лимерика со степенью бакалавра компьютерных наук и дипломом в инженера вычислительной техники.



19.09.2012

Созданная в феврале 2004 года служба Facebook превратилась в крупнейшую в мире социальную сеть, в которой более чем 900 млн пользователей обмениваться контентом со своими друзьями. Система Facebook Platform, запущенная в мае 2007 года, позволяет сторонним разработчикам писать приложения, интегрированные в Facebook. Первоначально эта платформа поддерживала широкий спектр языков программирования — включая Java, но теперь в ней есть специальный SDK только для JavaScript и PHP (а также поддержка приложений для iOS и Android-устройств). Однако проект по разработке ПО с открытым исходным кодом RestFB поддерживает API Java с тех пор, как платформа Facebook прекратила его поддержку (см. раздел Ресурсы).

Google App Engine (GAE) — это облачная система типа "платформа как услуга" (PaaS), которая позволяет зарегистрированным разработчикам выполнять свои приложения, написанные на Python, Java или в инфраструктуре Go on Google. В этой статье показано, как зарегистрировать приложение для Facebook, разработать его на Java и бесплатно установить на платформе GAE на благо всех пользователей, зарегистрированных в Facebook. (Отметим, что Google налагает ограничение на ежедневное использование ресурсов, потребляемых приложением, установленным в GAE).

Простое приложение, которое мы создадим, составляет список всех друзей пользователя с указанием их идентификаторов и фотографиями из профиля — как на странице друзей профиля пользователя Facebook старого образца. Чтобы разработать приложение, нужны:

  • учетная запись Facebook;
  • учетная запись Google;
  • IDE Eclipse с установленным плагином GAE (см. раздел Ресурсы);
  • знакомство с Eclipse.

Исходный код приложения содержится в загрузках для этой статьи.

Регистрация приложения

Первый шаг состоит в том, чтобы зарегистрировать свое приложение на Facebook и в GAE. Приложение лучше создавать на обеих платформах одновременно, чтобы информация, которую вы вводите, совпадала.

Регистрация приложения на Facebook

Войдите в Facebook и запустить приложение для разработчика по адресу: https://developers.Facebook.com/apps. (Те, кто делает это впервые, должны будут предоставить приложению доступ к своему профилю.)

Нажмите кнопку Create New App в верхнем правом углу страницы Apps, чтобы открыть диалоговое окно Create New App, показанное на рисунке 1.

Рисунок 1. Диалоговое окно Create New App на Facebook
Скриншот диалогового окна Create New App для Facebook

Введите допустимое имя и доступное пространство имен для приложения. Пространство имен — это уникальный идентификатор в одно слово, который будет использоваться в URL-адресе приложения на Facebook. (На рисунке 1 я ввел в качестве имени приложения My Old Friends, а в качестве пространства имен ― myoldfriends.) Оставьте невыбранным пункт о предоставлении бесплатного хостинга Heroku и нажмите кнопку Continue. В следующем диалоговом окне введите код CAPTCHA и нажмите кнопку Submit, чтобы открыть окно настройки основных параметров нового приложения, показаное на рисунке 2.

Рисунок 2. Диалоговое окно настройки основных параметров приложения для Facebook
Диалоговое окно настройки основных параметров приложения для Facebook

Обратите внимание на ключи App ID и App Secret в верхней части экрана (на рисунке 2 они скрыты). Facebook использует эти ключи для идентификации приложения. Держите их в секрете и не позволяйте другим разработчикам использовать их, чтобы ими не воспользовались злонамеренно без вашего ведома.

Введите в поле App Domains домен приложения. Это должен быть домен GAE, в котором вы зарегистрируете приложение на сайте для разработчиков GAE, так что он должен заканчиваться на .appspot.com. Например, на рисунке 2 я ввел значение myoldfacebookfriends.appspot.com. Этот домен уже недоступен, поэтому вам придется использовать другой. Он должен соответствовать идентификатору приложения, который вы используете при регистрации приложения в GAE.

В поле Select how your app integrates with Facebook выберите способ интеграции с Facebook Website with Facebook Login и введите URL-адрес сайта, состоящий из домена GAE, указанного в поле App Domains, с приставкой http://. (На рисунке 2 я указал http://myoldfacebookfriends.appspot.com.)

URL-адрес фона

По URL-адресу фона, указанному в основных параметрах приложения, Facebook определяет, где взять код для заполнения Canvas Page — пустой страницы в Facebook, на которой будет размещаться ваше приложение. Когда пользователь запрашивает Canvas Page, Facebook помещает URL-адрес фона в <iframe> на этой странице.

Выберите App on Facebook и введите URL-адрес фона для сервлета, в котором будет выполняться приложение. Для этого приложения URL-адрес фона заканчивается вопросительным знаком, указывающим на то, что параметры приложения будут передаваться через запрос URL-адреса, передаваемый в приложение. Безопасный URL-адрес фона ― то же, что и URL-адрес фона, за исключением того, что место http занимает https. Опять же, важен вопросительный знак в конце URL-адреса. (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/ — и нажмите кнопку Create Application. В поле Application Identifier укажите то же имя домена приложения, которое использовалось в основных параметров настройки приложения для Facebook. (Часть appspot.com уже заполнена). Можно использовать любое название приложения ― по этому названию производится поиск зарегистрированных приложений. Для остальных параметров оставьте значения по умолчанию.

Рисунок 3. Диалоговое окно GAE Create an Application
Диалоговое окно GAE Create an Application

Нажмите кнопку Create Application, чтобы завершить процесс регистрации в GAE.


Разработка приложения

В Eclipse создайте новый проект GAE, выбрав File > New > Web Application Project или нажав кнопку New Web Application Project в меню Google Services and Deployment Tools. Введите имя проекта и имя пакета. Снимите флажок Use Google Web Toolkit. Загрузите JAR-файл RestFB (см. раздел Ресурсы) и добавьте его в папку WEB-INF/lib проекта.

Добавьте в файл проекта web.xml определение сервлета для приложения. Мое определение приведено в листинге 1.

Листинг 1. Определение сервлета
<?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> тот же, что и в URL фона в окне настройки основных параметров приложения для Facebook, но без вопросительного знака.

С октября 2011 года для приложений Facebook требуется, чтобы функция Secure Sockets Layer (SSL) была включена; в GAE она по умолчанию отключена. Чтобы включить ее, добавьте в appengine-web.xml следующую строку:

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

Подписанный запрос к Facebook

Для создания тела приложения Facebook отправляет в адрес сервлета приложения подписанный запрос, используя метод HTTP POST. Этот запрос содержит информационное наполнение в 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;

      }

   }

}

Код информационного наполнения запроса можно расшифровать с помощью декодера Base64 из библиотеки Apache Commons Codec. Результат представлен в формате JavaScript Object Notation (JSON), и его можно преобразовать в объект Java с помощью процессора JSON Jackson. Загрузите JAR-файлы и добавьте их в проект (см. раздел Ресурсы). Чтобы создать объект, добавьте к классу FacebookSignedRequest вспомогательный статический метод, приведенный в листинге 3.

Листинг 3. Вспомогательный метод для кодирования и декодирования информационного наполнения запроса
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-class> в файле web.xml. Сначала нужно извлечь маркер OAuth из информационного наполнения запроса, используя класс SignedRequest, как показано в листинге 4.

Листинг 4. Извлечение маркера OAuth
String signedRequest = (String) request.getParameter("signed_request");
FacebookSignedRequest FacebookSR = null;
try {
   FacebookSR = FacebookSignedRequest.getSignedRequest(signedRequest);
} catch (Exception e) {
   // автоматически сгенерированный блок-ловушка TODO
   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

API KEY и Application Namespace в URL-адресе аутентификации те же, что и в диалоговом окне настройки основных параметров приложения Facebook. Permissions - это список разрешений, необходимых для приложения. По умолчанию все приложения имеют базовые разрешения, и для целей этой статьи не нужно добавлять никакие другие. (Ссылка на полный список доступных разрешений приведена в разделе Ресурсы.)

Внешний вид этой страницы можно изменить на странице Settings > Auth Dialog приложения Facebook для разработчиков. Обычно используется метод сервлета HttpServletRequest.sendRedirect(), но так как приложение будет выполняться в <iframe > в домене apps.Facebook.com, короткий фрагмент JavaScript, приведенный в листинге 5, заменяет местоположение окна браузера URL-адресом приложения.

Листинг 5. Код JavaScript переадресации по URL-адресу приложения
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();

}

API Graph Facebook

API Graph позволяет читать свойства и связи из социального графа Facebook. Можно читать отдельные поля, получать изображения любого объекта, углубляться в метаданные объекта и получать обновления в режиме реального времени.

С помощью действительного маркера OAuth можно создать DefaultFacebookClient из библиотеки RestFB и использовать его для извлечения данных из API Graph Facebook с помощью вызова fetchConnection(). Перейдите в Graph Explorer на Facebook по адресу: https://developers.Facebook.com/tools/explorer. Выберите разработанное вами приложение из раскрывающегося списка в верхнем правом углу и нажмите Get access token, чтобы получить доступ. Понажимайте на различные ссылки под заголовком Connections, чтобы увидеть результаты.

Чтобы получить список друзей пользователя, нажмите на ссылку friends. Обратите внимание, что значение URL в обозревателе имеет вид: id пользователя/friends. Параметр подключения при вызове функции обычно имеет то же значение, что и в Graph Explorer. Но поскольку приложение использует данные пользователя, вошедшего в систему, ID пользователя можно заменить на me, что дает значение me/friends. Вызов возвращает необработанный тип Connection, а так как это класс типа User, его необходимо добавить в качестве параметра. Окончательный вызов имеет вид:

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

Результат вызова метода fetchConnection() содержится в списке объектов List класса Connection. Класс Connection реализует интерфейс Iterable, так что каждый объект List из списка можно получить в с помощью расширенного цикла for:

for (List<User> myFriendsList : myFriends)

На каждой итерации цикла объект myFriendsList содержит текущий список пользователей для этой возвращенной страницы данных. Каждый объект User из этого списка используется для создания строки в таблице пользователей, которую создает сервлет. Из объекта User можно получить идентификатор и имя пользователя, но не изображение из его профиля. Однако Facebook предоставляет URL-адрес для извлечения изображения из профиля любого пользователя: https://graph.facebook.com/User ID/picture. Таким образом, чтобы составить URL-адрес изображения из профиля, нужно заменить User ID в URL идентификатором пользователя из объекта User. Используя тот же объект 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:

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

Окончательный вид метода doPost() сервлета показан в листинге 7.

Листинг 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
    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();

  }

}

Установка приложения

Когда сервлет создан, приложение готово к установке. Щелкните на значке Google в Eclipse и выберите пункт Deploy App Engine. После компиляции приложения и его загрузки на сервер вы (и любой другой пользователь Facebook) можете установить его в Facebook по адресу http://apps.facebook.com/APP ID/ и увидеть результаты.


Заключение

В этой статье показано, как зарегистрировать, реализовать и установить приложение Facebook на языке Java, размещенное в системе Google App Engine. Теперь, когда вы знакомы с основами, я предлагаю поэкспериментировать с разными вариациями.

Вместо того чтобы писать HTML-код непосредственно на странице, можно прибегнуть к более традиционному подходу "модель-представление-контроллер" (MVC), используя стандартный вызов RequestDispatcher.forward() для страницы JavaServer Pages (JSP).

Можно попробовать создать приложение, использующее некоторые дополнительные разрешения для данных, предоставленных API Graph. Передайте список разрешений, необходимых приложению, по URL-адресу аутентификации, добавляя каждое из них к параметру запроса scope. RestFB предоставляет вспомогательный метод —StringUtils.join()— для правильного создания списка. В качестве параметра он принимает один массив типа String; каждая запись массива представляет собой имя разрешения.

Наконец, можно попытаться воссоздать пример приложения, используя вместо RestFB проект Facebook-java-api Google Code — альтернативную реализацию API Facebook (см. раздел Ресурсы).


Загрузка

ОписаниеИмяРазмер
Пример кода для статьиj-fb-gaecode.zip5 КБ

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java
ArticleID=835952
ArticleTitle=Java-приложения для Facebook на базе Google App Engine
publish-date=09192012