Знакомство с протоколом публикации Atom, Часть 2: Ввод протокола публикации Atom (APP) в работу

Взаимодействие с такими развернутыми приложениями, как сетевые дневники или календари

В предыдущем выпуске данной серии был представлен краткий обзор протокола публикации Atom (APP). Настоящая статья продолжает знакомство с протоколом, показывая каким образом его можно использовать для организации взаимодействия с несколькими реальными развернутыми приложениями.

Как и раньше, данное обсуждение предполагает наличие у Вас понимания синдикации контента с использованием формата синдикации Atom 1.0 и общего представления о HTTP. Примеры написаны на языке Java 1.5 и используют последнюю промежуточную версию Apache Abdera реализации Atom с открытым исходным кодом, которая в настоящий момент разрабатывается Apache Software Foundation.

Джеймс Снелл, разработчик программного обеспечения, IBM

Джеймс Снелл (James Snell) является членом исследовательской лаборатории IBM WebAhead, занимающейся разработкой опытных образцов стандартов и технологий программного обеспечения, находящегося в стадии создания, для собственных нужд IBM. Его научно-исследовательские интересы охватывают широкий круг направлений современных технологий, а именно Atom, AJAX, REST, Open Source, персональные издательские системы, семантические и ситуационные Web-приложения. Он является активным участником проекта Apache Abdera, находящегося в настоящее время на этапе разработки и нацеленного на создание высокоэффективной и функционально законченной реализации стандартов формата синдикации Atom и протокола публикации Atom.



29.03.2007

Начало работы

Перед тем, как Вы начнете работать, убедитесь, что у Вас установлена последняя версия Apache Abdera. Загрузить ее можно из хранилища промежуточных версий Apache на http://svn.apache.org/repos/asf/incubator/abdera/java/trunk. Перед загрузкой убедитесь, что у Вас есть клиент промежуточной версии и выполните команду:

> svn co http://svn.apache.org/repos/asf/incubator/abdera/java/trunk

Загрузив исходный образ, Вы можете скомпоновать Abdera, используя Ant версии 1.6.5 или выше.

> cd trunk
> ant -f build/build.xml dist

По завершению компоновки, скомпилированные jar-файлы и зависимости располагаются во вновь созданной директории dist. Для запуска примеров в Вашем classpath должны быть следующие jar-файлы:

Таблица 1. Jar-файлы, необходимые для запуска примеров
Abdera (dist)Зависимости (dist/lib)
  • abdera.client.0.2.0-incubating-SNAPSHOT.jar
  • abdera.core.0.2.0-incubating-SNAPSHOT.jar
  • abdera.parser.0.2.0-incubating-SNAPSHOT.jar
  • abdera.protocol.0.2.0-incubating-SNAPSHOT.jar
  • axiom-api-1.0.jar
  • axiom-impl-1.0.jar
  • commons-codec-1.3.jar
  • commons-httpclient-3.0.1.jar
  • commons-logging-1.0.4.jar
  • geronimo-activation_1.0.2_spec-1.1.jar
  • geronimo-javamail_1.3.1_spec-1.1.jar
  • log4j-1.2.12.jar
  • stax-1.1.2-dev.jar
  • stax-api-1.0.jar

Сетевые дневники (блоги)

В соответствии с уставом IETF формата публикации Atom и рабочей группы протокола, протокол публикации Atom в первую очередь предназначен для использования при публикации и управлении сообщениями сетевых дневников. И не удивительно, что большинство поставщиков программного обеспечения для сетевых дневников, например, Google, SixApart, и Roller уже начали организовывать предварительную поддержку протокола.

Google's Blogger Beta

В начале августа 2006 года Google анонсировал долгожданное обновление своего сервиса блогов. Помимо других функций, теперь сервис поддерживает использование протокола публикации Atom для создания и редактирования сообщений.

Создать сообщение достаточно просто. Первое, что Вам необходимо знать, это URL той коллекции Atom, в которую будут отправлены новые сообщения. В Blogger лента Atom используется для синдикации контента блогов для предоставления читателям и организаторам зеркала коллекции протокола публикации Atom. Для нахождения URI коллекции необходимо только взглянуть на альтернативную ссылку в заголовке домашней страницы блога.

Листинг 1. Заголовок домашней страницы моего Blogger
<html>
  <head>
    <title>testing</title>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>
    <meta content='true' name='MSSmartTagsPreventParsing'/>
    <meta content='blogger' name='generator'/>
    <link rel="alternate" type="application/atom+xml" 
      title="testing - Atom" 
      href="http://beta.blogger.com/feeds/7352231422284704069/posts/full" />
    <link rel="alternate" type="application/rss+xml" 
      title="testing - RSS" 
      href="http://beta.blogger.com/feeds/7352231422284704069/posts/full?alt=rss" />
    <link rel="service.post" type="application/atom+xml" 
      title="testing - Atom" 
      href="http://beta.blogger.com/feeds/7352231422284704069/posts/full" />
    ...

Как только Вам станет известен адрес ленты Atom, Вы можете начать публиковать сообщения в блоге. В листинге 2 показан образец сообщения, которое Вы хотите отправить:

Листинг 2. Образец сообщения Blogger
POST /feeds/7352231422284704069/posts/full HTTP/1.1
Host: beta.blogger.com
Content-Type: application/atom+xml
Content-Length: 349
Authorization: GoogleLogin auth={auth token}

<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <id>urn:uuid:1332534422684714363</id>
  <title>Posting to Blogger</title>
  <author><name>James</name></author>
  <updated>2006-09-02T12:12:12Z</updated>
  <content type="xhtml">
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>This is an example post to the new blogger beta</p>
    </div>
  </content>
</entry>

Обратите внимание на некоторые важные моменты, касающиеся запроса и показанные в листинге 2. Во-первых, это заголовок Authorization (авторизация). Сервис Google с поддержкой протокола публикации Atom требует использования собственной схемы авторизации, которую, к счастью, можно легко реализовать. Во-вторых, реализация Google требует, чтобы запросы содержали заголовок Content-Length. Хотя на первый взгляд это и кажется несущественным, но у данного требования может быть и побочный эффект, приводящий к тому, что клиентам, отравляющим сообщения на сервер, перед отправкой необходимо вычислить размер публикуемого запроса, а это снижает эффективность запросов. И, наконец, в публикуемом сообщении содержится ID (идентификатор), автор, и обновленные значения элементов, которые Blogger просто игнорирует.

Шаг 1. Аутентификация

Первый шаг публикации сообщения в Blogger заключается в аутентификации с использованием схемы аутентификации GoogleLogin. Создайте вспомогательный класс GoogleLogin. В качестве его входной информации будут выступать ID и пароль пользователя, которые Вы используете для доступа к Вашей учетной записи на Google, и название того сервиса, к которому Вы обращаетесь. В данном случае название сервиса - "blogger".

Листинг 3. Схема GoogleLogin требует отправки простого HTTP POST на сервер аутентификации
public final class GoogleLogin {
  ...
  public static String getAuth(
    Client client, 
    String service, 
    String id, 
    String pwd) {
    try {
      StringRequestEntity stringreq =
        new StringRequestEntity(getRequest(id,pwd,service));
      RequestOptions options = client.getDefaultRequestOptions();
      options.setContentType("application/x-www-form-urlencoded");
      ClientResponse response = client.post(URI, stringreq, options);
      String auth = read(response.getInputStream());
      response.release();
      return auth.split("\n")[2].replaceAll("Auth=", "auth=");
    } catch (Exception e) {}
    return null;
  }
  ...
}

Вызов метода GoogleLogin.getAuth(...) с соответствующими правами приводит к созданию маркера права на доступ, который Вы можете использовать для аутентификации запросов на публикацию или редактирование сообщений в Blogger.

Шаг 2. Создание сообщения

Второй шаг публикации сообщения в Blogger заключается в создании сообщения Atom, которое Вы опубликуете с использованием Apache Abdera API объектной модели ленты (Feed Object Model):

Листинг 4. Создание сообщения в Blogger
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
Entry entry = factory.newEntry();
entry.setId(FOMHelper.generateUuid());
entry.setUpdated(new java.util.Date());
entry.addAuthor("James");
entry.setTitle("Posting to Blogger");
entry.setContentAsXhtml(
  "<p>This is an example post to the new blogger beta</p>");

Шаг 3. Публикация сообщения

На последнем шаге выполняется отправка сообщения на сервер Blogger:

Листинг 5. Публикация сообщения в Blogger
Client client = new CommonsClient(abdera);
String auth = GoogleLogin.getAuth(
  client, "blogger", 
  "your@user.id", 
  "your.password");
    
RequestOptions options = client.getDefaultRequestOptions();
options.setAuthorization("GoogleLogin " + auth);
    
BaseRequestEntity bre = new BaseRequestEntity(entry, false);
    
Response response = client.post(
  "http://beta.blogger.com/feeds/7352231422284704069/posts/full", 
  bre, options);

if (response.getStatus() == 201) 
  System.out.println("Success!");
else 
  System.out.println("Failed!");

В листинге 5 Вы можете увидеть все эти элементы вместе. Сначала считывается маркер права доступа и задается в качестве параметра запроса. Затем Вы используете BaseRequestEntity, вспомогательный класс Abdera, в качестве надстройки для публикуемого сообщения, чтобы гарантировать уверенность в том, что значение необходимого заголовка Content-Length рассчитано правильно. И наконец, отправляете сообщение на URL ленты Atom, указанный в заголовке домашней страницы Blogger. Если отправка прошла успешно, то сервер в ответ выдаст код состояния 201 HTTP.

Рисунок 1. Успешная отправка сообщения в Blogger
Скриншот успешной отправки сообщений в Blogger

Редактирование и удаление сообщений

С помощью протокола публикации Atom Вы также можете редактировать и удалять уже существующие сообщения:

Листинг 6. Изменение существующего сообщения
String location = // получение URI для редактирования сообщения
    
Document<Entry> entry_doc = client.get(location).getDocument();
entry = (Entry) entry_doc.getRoot().clone();
entry.setTitle("This is the changed title");
    
response = client.put(
  location, new BaseRequestEntity(entry,false), options);
Листинг 7. Удаление сообщения
String location = // получение URI для удаления сообщения

response = client.delete(location, options);

Roller Weblogger

Однако Google является не единственным провайдером сетевых дневников, который планирует поддержку протокола публикации Atom. Популярный пакет программ с открытым исходным кодом Roller Weblogger, используемый в качестве серверного приложения для нескольких больших корпоративных сетей с поддержкой сетевых дневников, например, сайт Sun (http://blogs.sun.com), и внутренний сервис сетевых дневников интрасети IBM, в настоящее время находится в процессе модернизации и организации поддержки APP. За исключением пары особенностей, процесс публикации сообщений в Roller аналогичен публикации сообщений в Blogger:

Листинг 8. Образец сообщения в Roller
POST /app/myblog/entries HTTP/1.1
Host: example.org
Content-Type: application/atom+xml
Authorization: Basic {user:password}

<entry xmlns="http://www.w3.org/2005/Atom">
  <id>urn:uuid:4BA4E6A3334F88813011571535258641</id>
  <title type="text">Posting to Roller</title>
  <updated>2006-09-01T23:32:05.880Z</updated>
  <author><name>James</name></author>
  <content type="html">
    <p>This is an example post to Roller</p>
  </content>
</entry>

Ключевые различия между интерфейсами Roller Atom и Blogger заключаются в том, что Roller предоставляет служебный документ APP для обнаружения доступных коллекций (в отличие от использования альтернативных ссылок на домашней странице сетевого дневника) и использует стандартизованную схему базовой аутентификации:

Листинг 9. Публикация в Roller
String start = "http://roller.example.org/app";
    
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
Entry entry = factory.newEntry();
entry.setId(FOMHelper.generateUuid());
entry.setUpdated(new java.util.Date());
entry.addAuthor("James");
entry.setTitle("Posting to Roller");
entry.setContentAsHtml("<p>This is an example post to Roller</p>");
    
Client client = new CommonsClient(abdera);
client.addCredentials(
  start, null, null, 
  new UsernamePasswordCredentials(
    "username", "password"));
    
// Получение URI коллекции из служебного документа
Document<Service> service_doc = client.get(start).getDocument();
Service service = service_doc.getRoot();
Collection collection = 
  service.getWorkspaces().get(0)
    .getCollections().get(0);
String uri = collection.getHref().toString();
      
Response response = client.post(uri, entry);

if (response.getStatus() == 201) 
  System.out.println("Success!");
else
  System.out.println("Failed!");

Публикация мультимедийных ресурсов

Еще одной важной особенностью реализации Atom публикации Roller является поддержка загрузки любых мультимедийных ресурсов. Например, чтобы загрузить подкаст на Ваш сервер, Вам необходимо просто заменить запись предыдущего сообщения на элемент запроса, представляющий MP3 для загрузки:

Листинг 10. Публикация аудио ресурсов в сетевом дневнике Roller
FileInputStream fis = new FileInputStream(
  "mypodcast.mp3");
InputStreamRequestEntity re = 
  new InputStreamRequestEntity(fis, "audio/mp3");
Client client = // инициализация клиента 
String uri = // получение uri коллекции 
      
RequestOptions options = client.getDefaultRequestOptions();
options.setHeader("Title", "mypodcast.mp3");
    
Response response = client.post(uri, re, options);
    
if (response.getStatus() == 201)
  System.out.println("Success!");
else
  System.out.println("Failed!");

Вы также можете использовать операции протокола публикации Atom для обновления, удаления, и составления перечня всех загруженных на сервер ресурсов.

Управление календарными событиями

При разработке протокола публикации Atom рабочая группа поставила важную цель, что хотя он изначально и нацелен на публикацию содержимого сетевых дневников, вики и аналогичных приложений, но должен быть применим и использоваться для более широкого круга приложений. В настоящее время исследуется поддержка протокола публикации Atom приложениями, которые не относятся к сетевым дневникам. Одним из таких примеров является приложение Google Calendar.

Google Calendar

Google Calendar - это сервис управления календарными событиями, предоставляющий пользователям возможность управления общественными или личными календарными событиями при помощи интерфейса на основе браузера или протокола публикации Atom:

Листинг 11. Образец публикации сообщения Atom в Google Calendar
POST /calendar/feeds/default/private/full HTTP/1.1
Host: www.google.com
Authorization: GoogleLogin auth={auth}
Content-Length: 834
Content-Type: application/atom+xml

<entry xmlns="http://www.w3.org/2005/Atom"
  xmlns:gd="http://schemas.google.com/g/2005" >
  <category scheme="http://schemas.google.com/g/2005#kind" 
    term="http://schemas.google.com/g/2005#event" />
  <id>urn:uuid:421D94DE83D298A91211571550147641</id>
  <title type="text">Tennis with Beth</title>
  <content type="text">Meet for a quick lesson</content>
  <updated>2006-09-01T23:56:54.772Z</updated>
  <author><name>James</name></author>
  <gd:transparency value="http://schemas.google.com/g/2005#event.opaque" />
  <gd:eventStatus value="http://schemas.google.com/g/2005#event.confirmed" />
  <gd:where valueString="Rolling Lawn Courts" />
  <gd:when startTime="2006-09-01T23:56:54.932Z" 
    endTime="2006-09-01T23:56:54.932Z" /></entry>

Важно заметить, что Google Calendar основан на той же самой серверной инфраструктуре протокола публикации Atom, что и новый Blogger Beta. Так же, как и в уже показанных примерах с Blogger, Calendar применяет специализированную схему аутентификации GoogleLogin и требует наличие заголовка Content-Length. Также необходимо наличие нескольких элементов расширения в сообщении Atom:

Листинг 12. Создание сообщения в Calendar
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
Entry entry = factory.newEntry();
entry.setId(FOMHelper.generateUuid());
entry.setUpdated(new java.util.Date());
entry.addAuthor("James");
entry.setTitle("New Calendar Event");
entry.setContentAsXhtml("<p>A new calendar event</p>");
    
entry.addExtension(TRANSPARENCY).setAttributeValue(
  "value", "http://schemas.google.com/g/2005#event.opaque");
entry.addExtension(EVENTSTATUS).setAttributeValue(
  "value", "http://schemas.google.com/g/2005#event.confirmed");
entry.addExtension(WHERE).setAttributeValue(
  "valueString", "Rolling Lawn Courts");
Element el = entry.addExtension(WHEN);
el.setAttributeValue("startTime", AtomDate.valueOf(new Date()).toString());
el.setAttributeValue("endTime", AtomDate.valueOf(new Date()).toString());

Как только сообщение создано, вся остальная процедура фактически аналогична публикации в Blogger:

Листинг 13. Публикация в Google Calendar
Client client = new CommonsClient(abdera);
String auth = GoogleLogin.getAuth(client, "cl", "username", "password"); 
RequestOptions options = client.getDefaultRequestOptions();
options.setAuthorization("GoogleLogin " + auth);
    
BaseRequestEntity bre = new BaseRequestEntity(entry, false);   
String uri = "http://www.google.com/calendar/feeds/default/private/full";    
Response response = client.post(uri, bre, options);
    
// calendar may return a 302 with a new URI to post to
if (response.getStatus() == 302) {
  uri = response.getLocation().toString();
  response = client.post(uri, bre, options);
}
    
if (response.getStatus() == 201) 
  System.out.println("Success!");
else
  System.out.println("Failed!");

Альтернативный подход

Одна из сложностей в подходе Google к управлению календарными событиями при помощи Atom заключается в необходимости наличия у сообщения, специального расширения фирмы-изготовителя. Альтернативный подход, предложенный научными сотрудниками IBM® Lotus®, заключается в использовании поддержки Atom для любого типа мультимедиа для работы с существующими стандартизованными форматами календарных событий, например iCal и xCal:

Листинг 14. Публикация события xCalendar в коллекции Atom
POST /calendar HTTP/1.1
Host: example.org
Content-Type: application/calendar+xml
Content-Length: nnnn

<?xml version="1.0" encoding="UTF-8"?>
<vcalendar version="2.0"
  prodid="-//hacksw/handcal//NONSGML 1.0//EN">
 <vevent>
  <uid>19970901T130000Z-123401@host.com</uid>
  <dtstamp>20060901T130000Z</dtstamp>
  <dtstart>20060901T163000Z</dtstart>
  <dtend>20060901T164000Z</dtend>
  <summary>Tennis with Beth</summary>
  <class>PUBLIC</class>
 </vevent>
</vcalendar>

После публикации в коллекции, сервер создает сообщение Atom, отображающее опубликованное событие:

Листинг 15. Запись в календаре, созданная сервером Atom
HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml; charset="utf-8"
Content-Location: http://example.org/calendar/1.atom
Location: http://example.org/calendar/1.atom

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
 <title>Tennis with Beth</title>
 <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
 <updated>2006-09-01T18:30:02Z</updated>
 <author><name>James</name></author>
 <summary type="text">Tennis with Beth</summary>
 <link rel="alternate" type="text/calendar"
   href="http://example.org/calendar/1.ics" />
 <content type="application/calendar+xml"
   src=http://example.org/calendar/1.xml/>
 <link rel="edit" type="application/atom+xml"
   href="http://example.org/calendar/1.atom" />
 <link rel="edit-media" type="application/calendar+xml"
   href="http://example.org/calendar/1.xml" />
</entry>

Обратите внимание, что при таком подходе нет необходимости в каких-либо расширениях формата Atom, и реализации могут продолжать работать с существующими форматами ведения календаря.

Хранение информации

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

Например, недавно Google анонсировал новую бета-версию службы Google Base, предназначенной для хранения произвольной информации для большого числа сервисов сервера приложений:

Листинг 16. Образец публикации в Google Base
POST /base/feeds/items HTTP/1.1
Host: www.google.com
Authorization: GoogleLogin auth={auth}
X-Google-Key: key={key}
Content-Type: application/atom+xml
Content-Length: 632

<?xml version='1.0'?>
<entry xmlns="http://www.w3.org/2005/Atom"
  xmlns:g="http://base.google.com/ns/1.0">
  <id>urn:uuid:1215d395-cfb1-4faa-b1cd-12da123e3a7a</id>
  <category scheme="http://base.google.com/categories/itemtypes" 
    term="products"/>
  <title type='text'>Acme 2000 series laptop</title>
  <content type='xhtml'>
    <div xmlns='http://www.w3.org/1999/xhtml'>
      The fastest Acme Laptop yet...
    </div>
  </content>
  <link rel='alternate' type='text/html' 
    href='http://www.provider-host.com/123456789'/>
  <g:label>Computer</g:label>
  <g:label>Laptop</g:label>
  <g:label>fastest laptop</g:label>
  <g:item_type>products</g:item_type>
</entry>

Благодаря своей гибкой архитектуре и поддержке разнообразных мультимедийных ресурсов протокол публикации Atom является API управления данными общего назначения в сети Web.

Забегая вперед

В данной статье представлено несколько практических реализаций публикации Atom, которые уже введены в действие и используются тысячами пользователей. Для поддержки приведенных примеров, в данной статье продемонстрировано использование проекта Apache Abdera с открытым исходным кодом для взаимодействия с различными сервисами управления данными, сетевыми дневниками и календарными событиями. В следующем выпуске данной серии будет представлен подробный обзор проекта Apache Abdera, включая тщательный анализ API объектной модели ленты и набора характеристик, а именно XPath, преобразования XSLT, маскирование контента, и поддержку цифровой подписи XML.


Загрузка

ОписаниеИмяРазмер
Sample Eclipse Project with the example codex-atompp2-appexamples.zip46KB

Ресурсы

Научиться

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

Обсудить

Комментарии

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=XML
ArticleID=205010
ArticleTitle=Знакомство с протоколом публикации Atom, Часть 2: Ввод протокола публикации Atom (APP) в работу
publish-date=03292007