Introduction to the Java Portlet Specification


By David DeWolf September 8, 2005

Перевод - Lazebniy Andrei


Java Portlet Specification (изначально созданная с использованием JSR-168) предоставляет стандартные возможности для разработки портальных компонентов при помощи языка программирования Java. Эта спецификация, выпущенная в октябре 2003 г., становится все более популярной не только в качестве стандарат для традиционных порталов, но также основы для использования «плагинов» для стандартных веб-приложений. Это введение в Java Portlet Specification разъяснит основы порталов и портлетов. Она поможет понять, что такое Java Portlet API и начать разрабатывать удобные портлеты.



Порталы, портлеты и Java Portlet Specification


Портал представляет собой веб-приложение, которое отображает содержание многих ресурсов. Портлетами являются веб-компоненты, которые генерируют фрагменты контента (обычно части разметки, такие как HTML, XML или WML). Путем объединения контента, сгенерированного различными портлетами портал способен генерировать интрефейс одиночного пользователя, который интегрирует множество отдельных ресурсов. В дополнение к сервисам объединения корпоративные порталы часто предоставляют дополнительные возможности, такие как персонализация отдельного входа в систему, однако доступность и способ применения подобных сервисом различны.


Портал взаимодействует с клиентами, обычно веб-браузерами, посредством ряда запросов и ответов. Когда портал получает запрос, он переводит его в серию запросов, предназначенных конкретным портлетам. Эти отдельные запросы затем перенаправляются к конкретным портлетам для обработки.


Портал использует портлет-контейнер для управления жизненным циклом портлетов. Портлет-контейнер отвечает за использование, обработку запросов и удаление портлетов. Java Portlet Specification обеспечивает объединение совместимого портлет-контейнера и портлетов. Этот тип стандартизации обеспечивает портабельность портлетов.


По своему дизайну Java Portlet Specification очень сходна с Java Servlet Specification. По существу, Java Portlet Specification построена над Java Servlet Specification 2.3 и Java Server Pages version 1.2 и заимствует свои объекты везде, где возможно. Поскольку портлет-контейнер должен выполняться внутри совместимого сервлет-контейнера (или использовать все функции, предоставленные совместимым контейнером), портлеты способны пересылать запросы сервлетам, JSP и прочим стандартным веб-ресурсам. Портлеты, севрлеты, JSP и прочие веб-ресурсы упакованы в специальное веб-приложение, называемое портлет-приложением.



Основы портлета


Основы создания портлетов очень схожи с основами создания сервлетов. Вдобавок к обеспечению того, что все портлеты выполняются в стандартной сервлетной среде, API портлетной спецификации моделируются по принципу сервлета. Интерфейсы Portlet, PortletConfig, PortletRequest и PortletResponse очень похожи на их сервлет-двойников. Как и в случае с сервлетами, портлет будет обеспечивать множественные запросы клиентов (часто одноверменно) во время работы. По этой причине портлеты имеют проблемы с одновременным доступом из многих потоков и не должны использовать члены экземпляров классов.


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

Запросы портлетов, ответы и сессии


API портлетов особо заботятся о том, чтобы разделить обработку запросов и исполнение ответов. Это разделение критически важно. Поскольку порталы объединяют фрагменты из множественных портлетов, каждый запрос портала потребует, чтобы эти портлеты, не заданные в действии, были переинтерпретированы. Если обработка и интерпретирование портлета объединены, это переинтерпретирование потребует повторной обработки. Это может привести к чему угодно – от дублирования данных до ненужного исполнения логики обработки.


Интерфейсы ActionRequest и ActionResponse используются портлетом для обработки действий – типичных подач форм. ActionRequest дает возможность работать с двоичными данными, отправленными клиентом. ActionResponse позволяет портлеты отвечать и манипулировать запросом , устанавливая PortletMode (рассмотрено ниже), WindowState (рассмотрено ниже) и параметрами интерпретации. Разработчики портлетов также могут перенаправлять запрос через ActionResponse.



RenderRequest используется, чтобы сообщить портлету параметры интерпретации. RenderRequest не имеет доступа к оригинальным параметрам, отправленным ActionRequest клиентом. Вместо этого, параметры интерпретации используются для пересылки информации из фазы действия в фазу интерпретирования. Интерфейс RenderResponse предоставеляет портлету механизм сообщения между сгенерированным контентом и клиентом (часто посредством портала).



PortletSession iдоступна через любой из PortletRequest. PortletSession содежит две разные области действия – область действия приложения и область действия портлета. Атрибуты области действия приложения доступны абсолютно всем веб-ресурсам в рамках применения портлета. Атрибуты, находящиеся на портлетном уровне должны быть доступными только на начальном этапе, котрый добавляет их в сессию. Portlet Specification не препятствует атрибутам области действия портлета в доступности для глобальных ресурсов. Вместо этого спецификация определяет, что 'Атрибуты, хранящиеся в (области действи япортлета) незащищены от прочих веб-компонентов портлетного приложения. Они просто соответственно разделены в пространстве имен'.


Внимание: Java Servlet Specification требует, чтобы два контекста никогда не разделяли один и тот же экземпляр сессии (session instance). По этой причине невозможно разделить информацию сессии для использования двумя портлетными приложениями (или портлетным приложением и порталом).

Режимы портлетов и состояния окон


Режимы портлетов и состояния окон используются для коммуникации с состоянием видимости портлета. Состояния окон расширяют и объединяют в себе относительный размер, предоставленный портлету для интерпретирования. Portlet Specification предоставляет три обязательных состояния окна. Минимизированные портлеты определены как единственные или же главным образом демонстрируемые портлеты. Портлеты, имеющие «нормальный» WindowState обычно делят область интерпретации с множественными портлетами.


Режимы портлетов указывают текущий вид портлетов. Режимы по умолчанию включают VIEW, EDIT и HELP. Портлеты должны генерировать соответствующую информацию каждый для каждого из этих режимов. Обычно режим редактирования предоставляет пользователю возможность настроить поведение портлета, режим помощи предоставляет инструкции и прочую полезную информацию касательно портлета, а режим просмотра демонстрирует контент согласно текущему состоянию портлета.


У портлетов есть возможность изменять свое собственное состяние просмотра путем изменения их собственного Portlet Mode и Window State в процессе ActionRequest. Это делается с помощью методов ActionResponse: setWindowState и setPortletMode. Также могут предоставляться режимы пользовательских настроек.




Настройки портлета



Настройки портлета предоставляют разработчику механизм для постоянной конфигурации, и создания пользовательских настроек и персонализации конкретного пользователя. Интерфейс PortletPreferences предоставляет методы, необходимые для чтения, записи и сброса настроек. Настройки могут быть обновлены тольок через ActionRequests, однако они доступны всем PortletRequests.

Сведение всего этого вместе


Связывание свободных концов


Класс GenericPortlet дает возможность дефолтного применения интрефейса портлета. Путем расщирения GenericPortlet разработчики портлета пользуются преимуществами встроенного интепретатора режимов портлета и дефолтных применения методов жизненного цикла. Пример Hello World внизу заимствует применение GenericPortlet.



Библиотеки тэгов портлетов


Спецификация портлета предоставляет библиотеки тэгов, которые используются для разработки JSP, которые интрепретируют фрагменты портлетов. Эта библиотека содержит тэги, которые могут быть использованы для определения объектов портлетов в пределах страницы, генерирования портлетных url'ов и генерирования уникальных портлетных пространств имен. Пример внизу использует эти библиотеки тэгов, чтобы сгенерировать страницу редактирования портлета (см. ссылку на образец кода).



Hello World!, стиль портлета


В приложенном образце Hello World! Демонстрируется простая интепретация и обработка действия. При первой интерпретации doView вызывается методом интепретации GenericPortlet. Этот метод отображает изначальное приветствие.



public void doView(RenderRequest req, RenderResponse res)
throws IOException {
PrintWriter out = res.getWriter();
out.println(getGreeting(req) + " World!");
}


Когда управление порталом используется для перекючения режима портлета на редактирование, портлет отображает экран редактирования, позволяющий пользователю изменить свое приветствие. doEdit вызывается применением GenericPortlet интепретатора. В этом методе вы используете диспетчер запросов для пересылки запроса на JSP, который сгненерирует фрагмент контента.


public void doEdit(RenderRequest req, RenderResponse res)
throws PortletException, IOException {
PortletRequestDispatcher dispatcher =
getPortletContext().getRequestDispatcher("/edit.jsp");
dispatcher.include(req, res);
}


страница JSP использует несколько портлетных тэгов для генерирования URL действия, который будет использован для обработки этой страницы.



<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<portlet:defineObjects/>
<portlet:actionURL var="url" portletMode="view"/>
<FORM method="POST" action="<%= url %>">
<TABLE>
<TR><TD>Greeting</TD>

<TD><INPUT type="text" name="greeting"
value="<%= renderRequest.getParameter("greeting") %>"/>
</TD>
<TD colspan="2"><INPUT type="submit" value="Save"/></TD>
</TR>
</TABLE>

</FORM>

Наконец после сабмишена контейнер вызывает метод processAction портлета. Этот метод устанавливает параметр интепретатора, который может быть использован для интерпретирования портлета.



public void processAction(ActionRequest req, ActionResponse res)
throws PortletException {
String greeting = getGreeting(req);
res.setRenderParameter("greeting", greeting);
}


Полный код образца портлета доступен для download.



Выводы


Основы разарботки портлетов весьма сходны с основами разработки сервлетов. Веб-разработчикам, которые знают основы создания портлетов, включая генерирование фрагментов и разделение действий и интерпретирование запросов, разработка портлетов должна показаться вполне несложной. В моей следующей статье я обращусь к применению портлетов на Apache Pluto (референтное применение Java Portlet Specification) и покажу, как можно повысить производительность путем использования Pluto в качестве среды разработки lightweight.



Ссылки



  • The Java Portlet Specification
  • The Java Portlet API

Об авторе


David DeWolf в течении шести лет разарбатывает веб-приложения, порталы и портлеты. Он является членом управляющего комитета проекта
Apache Portals
и принимает активное участие в
Apache Pluto
, референтном применении Portlet Specification. В данный момент David работает в
Digital Focus
, предоставляющем услуги разработки ПО, тренинга и консультативных услуг в сфере ИТ для Fortune 1000 и среднего размера предприятий. С ним можно связаться по
author@daviddewolf.com