Эта статья взята из книги «Портлеты в действии» из Manning Publications. Он является частью серии из трех частей, в которой создается пример портлета с использованием Spring 3.0 Portlet MVC. Оглавление, форум авторов и другие ресурсы можно найти по адресу http://manning.com/sarin/ .
Это первая статья в серии из трех частей, в которой мы рассмотрим разработку портлетов с использованием среды Spring 3.0 Portlet MVC. В первой части этой серии статей показано, как создать простой портлет Hello World с помощью среды Spring 3.0 Portlet MVC и развернуть его на сервере портала Liferay 5.2.3. В этой статье предполагается, что вы знакомы с основами среды Spring.
В этой статье для разработки портлета Hello World используется следующее программное обеспечение:
Начнем с импорта прилагаемого проекта HelloWorld Eclipse, который содержит все необходимые файлы для нашего портлета Hello World.
Структура проекта Структура
проекта, описанная в этом разделе, носит общий характер и может использоваться для разработки портлетов для любого сервера портала. После того, как вы импортируете проект HelloWorld в свою среду разработки Eclipse, вы найдете в нем следующие каталоги:
- src — содержит исходный код проекта, который включает классы портлетов и служебных программ.
- build — содержит WAR-файл, который генерируется при сборке проекта с использованием ANT.
- css — содержит CSS-файлы для проекта, полезно, если вы не используете внешний вид, предоставляемый сервером портала.
- images — Содержит изображения, используемые портлетами в проекте.
- js — содержит файлы JavaScript, используемые портлетом. Портлеты также могут использовать библиотеки JavaScript, такие как DWR, DOJO и jQuery, которые обычно упакованы в файл JAR и доступны портлетам напрямую из файла JAR. В большинстве случаев портлеты состоят из нескольких страниц информации, и на некоторых из этих страниц может потребоваться JavaScript для таких целей, как создание HTML-виджетов на лету и использование AJAX.
- lib — содержит файлы JAR, которые требуются во время сборки, но не должны быть упакованы с созданным файлом WAR, например, JUnit и файлы JAR портлета. JAR-файл JUnit необходим для запуска модульных тестов во время сборки, а JAR-файл портлета необходим для компиляции классов портлета.
- WEB-INF / jsp — содержит файлы JSP, используемые в проекте. Мы будем использовать JSP в качестве технологии просмотра, но для создания страниц портлетов можно использовать другие технологии просмотра, такие как Velocity и Facelets.
- WEB-INF / lib — содержит файлы JAR, которые требуются портлетам во время сборки и во время выполнения.
Теперь, когда мы знаем структуру нашего проекта, давайте посмотрим на файлы JAR, которые нам нужны для разработки / развертывания портлета Hello World.
Добавление необходимых файлов JAR
Чтобы создать портлет Hello World с помощью Spring Portlet MVC, вы можете либо загрузить последнюю версию Spring , которая содержит файлы JAR, необходимые для создания и развертывания вашего портлета, либо использовать файлы JAR, поставляемые с проект HelloWorld.
Следующие файлы JAR должны присутствовать в каталоге WEB-INF / lib проекта:
- org.springframework.asm-3.0.0-RELEASE
- org.springframework.beans-3.0.0-RELEASE (добавьте этот файл в путь сборки вашего проекта)
- org.springframework.context-3.0.0-RELEASE (добавьте этот файл в путь сборки вашего проекта)
- org.springframework.core-3.0.0-RELEASE
- org.springframework.expression-3.0.0-RELEASE
- org.springframework.web-3.0.0-RELEASE (добавьте этот файл в путь сборки вашего проекта)
- org.springframework.web.portlet-3.0.0-RELEASE (добавьте этот файл в путь сборки вашего проекта)
- org.springframework.web.servlet-3.0.0-RELEASE
Добавьте portlet.jar из TOMCAT_HOME \ common \ lib \ ext в каталог lib проекта (не WEB-INF / lib), где TOMCAT_HOME ссылается на каталог Tomcat внутри вашей установки Liferay.
Давайте теперь посмотрим на файлы конфигурации и классы, которые вам понадобятся для создания портлета Hello World с использованием среды Spring 3.0 Portlet MVC.
Класс контроллера / обработчика
В Spring Portlet MVC класс контроллера / обработчика (а не класс портлета) содержит действительную логику обработки запросов для портлета. В листинге 1 показан класс HelloWorldController.
Класс перечисления 1 HelloWorldController
public class HelloWorldController implements Controller{ #1 public void handleActionRequest(ActionRequest request, ActionResponse response)throws Exception { } public ModelAndView handleRenderRequest (RenderRequest request, RenderResponse response) throws Exception { Map<String, Object> model = new HashMap<String, Object>(); model.put("helloWorldMessage", "Hello World"); return new ModelAndView("helloWorld", model); #2 }}
# 1 Обработчик реализует интерфейс контроллера
# 2 handleRenderRequest возвращает ModelAndView
Обработчик HelloWorldController реализует интерфейс org.springframework.web.portlet.mvc.Controller, который определяет два метода:
- handleActionRequest — такой же, как метод действия портлета
- handleRenderRequest — такой же, как метод визуализации портлета
Метод handleRenderRequest в HelloWorldController возвращает ModelAndView, который содержит данные модели и информацию о просмотре.
В портлетах метод рендеринга обычно создает контент, отправляя запрос рендеринга на страницу JSP (или любую другую технологию представления), и данные, которые должны быть отображены страницей JSP, передаются как атрибуты запроса. Объект ModelAndView содержит данные модели (данные для визуализации) и информацию о представлении (страница JSP), которые используются средой Spring Portlet MVC для отправки запроса рендеринга в представление и передачи данных модели. Поскольку среда Spring Portlet MVC заботится об отправке запроса и передаче данных на страницу JSP, мы не используем PortletRequestDispatcher в методе handleRenderRequest.
Объект ModelAndView в классе HelloWorldController содержит модель (переменную модели в методе handleRenderRequest в листинге 1) в качестве объекта Map и имя представления (строковый параметр helloWorld конструктора ModelAndView в листинге 1) в качестве объекта String. Сообщение «Hello World», которое мы хотим показать с помощью страницы JSP, передается как атрибут модели с именем helloWorldMessage.
Страница JSP Страница
helloWorld.jsp в нашем примере портлета показывает сообщение «Hello World»:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page contentType="text/html" isELIgnored="false" %><c:out value="${helloWorldMessage}"/>
В листинге 1 мы поместили атрибут модели helloWorldMessage со значением Hello World. Среда Spring Portlet MVC преобразует атрибуты модели (такие как атрибут helloWorldMessage) для запроса атрибутов, чтобы страница JSP могла легко получить доступ к атрибутам модели.
На этой странице JSP код <c: out value = «$ {helloWorldMessage}» /> записывает сообщение «Hello World» в поток ответов, поскольку атрибут запроса helloWorldMessage содержит Hello World в качестве значения.
Дескриптор развертывания
портлета Если вы используете инфраструктуру Spring Portlet MVC для создания своего портлета, то обычно вы не будете создавать пользовательский класс портлета. Вместо этого вы будете повторно использовать класс DispatcherPortlet в Spring Portlet MVC. Класс DispatcherPortlet расширяет класс GenericPortlet и отвечает за отправку запросов портлетов соответствующему обработчику / контроллеру. В листинге 2 показан файл portlet.xml для примера портлета Hello World.
Перечисление 2 portlet.xml
<portlet> <portlet-name>helloWorld</portlet-name> <portlet-class> org.springframework.web.portlet.DispatcherPortlet #1 </portlet-class> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <resource-bundle>content.Language-ext</resource-bundle> <portlet-info> #2 <title>Hello World</title> </portlet-info></portlet>
# 1
Элемент DispatcherPortlet класса MVC для Spring Portlet # 2 <portlet-info> для заголовка портлета
Cueballs в коде и тексте
В # 1 класс DispatcherPortlet инфраструктуры Spring Portlet MVC указывается в качестве класса портлета. На # 2 мы используем элемент <portlet-info>, чтобы указать заголовок портлета.
Контекст веб-приложения
В любом приложении Spring Framework, ядром приложения является контекст приложения, который определяет объекты (которые являются частью приложения) и их взаимозависимости. Контекст приложения представлен в виде файла XML, который определяет объекты приложения в виде bean-компонентов.
В листинге 3 показаны компоненты, определенные в XML-файле контекста приложения для портлета Hello World. Имя файла контекста веб-приложения должно быть <portlet_name> -portlet.xml, где <portlet_name> — это имя портлета, как определено элементом <portlet-name> в файле portlet.xml. Этот файл должен находиться в папке WEB-INF вашего проекта.
Перечисление 3 helloWorld-portlet.xml
<?xml version="1.0" encoding="UTF-8"?><beans … > <bean id="helloWorldController" #1 class="code.listing.HelloWorldController"/> <bean id="portletModeHandlerMapping" #2 class="org.springframework.web.portlet.handler.[CA] PortletModeHandlerMapping"> <property name="portletModeMap"> <map> <entry key="view"> #3 <ref bean="helloWorldController" /> #3 </entry> #3 </map> </property></bean> <bean id="viewResolver" #4 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean></beans>
# 1 Определение контроллера / обработчика
# 2 Режим портлета и отображение обработчика
# 3 Режим VIEW сопоставлен с HelloWorldController
# 4 Просмотр распознавателя
На # 1 мы определяем обработчик HelloWorldController. На # 2 bean-компонент PortletModeHandlerMapping отображает текущий режим портлета на обработчик / контроллер, отвечающий за обработку запросов в этом режиме. На # 3 режим портлета VIEW портлета Hello World отображается на HelloWorldController, что означает, что любой запрос (визуализация или действие), отправленный портлетом в режиме VIEW, будет обрабатываться HelloWorldController. На # 4 специальный компонент InternalResourceViewResolver используется для сопоставления имен представлений (используемых в вашем коде Java) с фактическим представлением (которое может быть сервлетом или JSP). Он использует свойство viewClass для определения класса, ответственного за генерацию представления. Если вы используете JSP, содержащие JSTL, вам следует указать значение свойства viewClass как JstlView. Значение свойства префикса предваряется,и значение свойства суффикса добавляется к имени представления, чтобы создать URL, ссылающийся на фактическое представление. В примере с портлетом Hello World имя представления helloWorld возвращается методом handleRenderRequest из HelloWorldController (см. Листинг 2), который преобразуется в фактическое представление с помощью InternalResourceViewResolver путем добавления / WEB-INF / jsp / и добавления .jsp к Здравствуйте, имя просмотра. Это делает URL для фактического представления /WEB-INF/jsp/helloWorld.jsp.Это делает URL для фактического представления /WEB-INF/jsp/helloWorld.jsp.Это делает URL для фактического представления /WEB-INF/jsp/helloWorld.jsp.
XML контекста
корневого веб-приложения XML контекста корневого веб-приложения относится к XML-контексту веб-приложения, связанному с приложением портлета. XML-файл контекста веб-приложения для портлета содержит bean-компоненты, специфичные для портлета, а XML-файл контекста корневого веб-приложения содержит bean-компоненты, общие для портлетов в приложении с портлетами. Компонент, определенный в корневом XML-контексте контекста веб-приложения, может быть переопределен специфичным для портлета XML-контекста приложения путем определения компонента с тем же идентификатором компонента.
Имя XML-файла контекста корневого веб-приложения должно быть applicationContext.xml. Поскольку мы не создаем никаких компонентов на уровне приложения с портлетами, мы создадим пустой XML-файл контекста корневого веб-приложения, как показано в листинге 5.
Перечисление 5 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?><beans ....></beans>
Теперь рассмотрим дескриптор развертывания веб-приложения для нашего приложения с портлетами.
Дескриптор развертывания веб-приложения
В дескрипторе развертывания веб-приложения мы определяем ViewRendererServlet из Spring, который отвечает за отображение наших страниц JSP. Bean-компонент InternalResourceViewResolver (см. Листинг 3) разрешает имя представления в фактическое представление, а рендеринг представления выполняется сервлетом ViewRendererServlet. ViewRendererServlet действует как мост между портлетом и представлением. В листинге 6 показана конфигурация ViewRendererServlet в файле web.xml.
Перечисление 6 web.xml
<web-app ....><servlet> <servlet-name>ViewRendererServlet</servlet-name> <servlet-class> org.springframework.web.servlet.ViewRendererServlet </servlet-class></servlet><servlet-mapping> <servlet-name>ViewRendererServlet</servlet-name> <url-pattern>/WEB-INF/servlet/view</url-pattern></servlet-mapping> </web-app>
Далее мы создадим пакет ресурсов для нашего портлета.
Пакет ресурсов
Файл Language-ext.properties — это пакет ресурсов, используемый портлетом Hello World. Свойства, определенные в файле Language-ext.properties, включают следующее:
category.helloWorld=Spring Portletjavax.portlet.title=My Hello World portlet
Значение свойств, определенных в файле Language-ext.properties, заключается в следующем:
- category.helloWorld — указывает имя категории, под которой портлет отображается Liferay.
- javax.portlet.title — указывает заголовок портлета. Имя свойства должно быть javax.portlet.title, чтобы контейнер портлета рассматривал его как заголовок портлета.
Добавьте портлет в категорию Liferay с помощью liferay-display.xml
Файл liferay-display.xml позволяет указать категорию, в которой вы хотите, чтобы портлет отображался. Содержимое файла liferay-display.xml показано здесь:
<display> <category name="categoryhelloWorld"> <portlet id="helloWorld" /> </category> </display>
Важные элементы файла liferay-display.xml:
- <категория> — атрибут name относится к ключу в файле Liferay-ext.properties, который определяет категорию, в которой должен отображаться портлет.
- <portlet> — атрибут id должен быть именем портлета, определенным элементом <portlet-name> в файле portlet.xml.
Сконфигурируйте специфичные для Liferay функции с помощью liferay-portlet.xml Файл
liferay-portlet.xml позволяет настроить специфичные для Liferay функции для портлета. Файл liferay-portlet.xml в нашем случае содержит элемент liferay-portlet-app следующим образом:
<liferay-portlet-app> <portlet> <portlet-name>helloWorld</portlet-name> <instanceable>true</instanceable> </portlet> </liferay-portlet-app>
Важными элементами файла liferay-portlet.xml являются:
- <portlet-name> — имя портлета, определенное элементом <portlet-name> в файле portlet.xml.
- <instanceable> — если true, один и тот же портлет может появляться на странице портала более одного раза. Значение по умолчанию неверно.
На этом создание необходимых файлов для проекта HelloWorld завершено. Теперь мы готовы построить проект HelloWorld с использованием Ant.
Сборка и развертывание вашего портлета на Liferay
Первое, что вам нужно сделать перед сборкой проекта HelloWorld, — это изменить свойство liferay.portal.home файла build.properties, чтобы оно указывало на каталог установки Liferay 5.2.3.
Чтобы построить проект в Eclipse IDE, щелкните правой кнопкой мыши файл build.xml, выберите «Выполнить как»> «Сборка Ant» и выберите цель сборки из списка доступных целей, как показано на рисунке 1.
Рисунок 1. Цели Ant, определенные в build.xml. Цель сборки выбрана по умолчанию. Цели компиляции и очистки также могут выполняться отдельно, если целью является только компиляция или очистка проекта.
Инструмент сборки Ant выполняет следующие действия при выполнении цели сборки:
- Удаляет сгенерированный файл WAR из каталога сборки. Это достигается путем выполнения чистой цели.
- Компилирует исходный код Java в каталог WEB-INF / classes, создает каталог содержимого и копирует в него файл Language-ext.properties. Это достигается путем выполнения цели компиляции.
- Создает файл WAR в каталоге сборки и копирует созданный файл WAR в LIFERAY_HOME / deploy (это каталог горячего развертывания Liferay). Это достигается путем выполнения цели сборки. LIFERAY_HOME ссылается на каталог установки Liferay.
- Если ваш сервер портала Liferay уже запущен, то выполнение цели сборки приведет к горячему развертыванию портлета Hello World. Если сервер не работает, портлет развертывается при запуске сервера. Во время развертывания информация из liferay-display.xml используется для регистрации портлета на сервере портала Liferay.
Добавьте портлет Hellow World
Когда портлет развернут в Liferay, он становится доступным пользователю, когда пользователь выбирает опцию «Добавить приложение» в док-станции. Чтобы добавить портлет Hello World, выполните следующие действия:
- Войдите на сервер портала Liferay.
- Выберите опцию Add Application из док-станции (см. Рисунок 2).
Рисунок 2 Опция Add Application позволяет аутентифицированным пользователям добавлять портлеты на страницу портала. Пользователь может добавлять портлеты на страницу портала, только если у него есть разрешение на это. По умолчанию пользователь может добавлять или удалять портлеты на созданной пользователем странице портала.
Добавьте портлет Hello World на свою домашнюю страницу, как показано на рисунке 3.
Рисунок 3 Портлет Hello World под категорией Spring Portlet; Портлет My Hello World на странице портала
На рисунке 3 вы видите, что новая категория Spring Portlet была добавлена в список доступных категорий. Заголовок, назначенный портлету Hello World, отображается под категорией. Портлет Hello World при добавлении на страницу портала показывает сообщение «Hello World».
Как это устроено
На рисунке 4 показано, что происходит в примере портлета Hello World, который мы создали в этой статье. Мы знаем, что DispatcherPortlet является наиболее важным классом Spring Portlet MVC, поскольку он расширяет класс GenericPortlet и действует как класс портлетов для наших портлетов на основе Spring Portlet MVC. Так что же делает DispatcherPortlet? Если у вас есть опыт работы со структурой Struts, вы можете тесно связать DispatcherPortlet с классом RequestProcessor в структуре Struts. DispatcherPortlet лежит в основе среды Spring Portlet MVC, и, как и RequestProcessor платформы Struts, он отвечает за координацию всех действий по обработке запросов при получении запроса портлета.
Рисунок 4 Обработка запросов в Spring Portlet MVC. DispatcherPortlet выступает в качестве фронт-контроллера приложения. DispatcherPortlet находит обработчик, сопоставленный с запросом, используя HandlerMapping. Результат выполнения обработчика ModelAndView используется для разрешения фактического представления, подлежащего визуализации, и отправки запроса в ViewRendererServlet для визуализации.
Cueballs в рисунке
Когда запрос Disletcher получен классом DispatcherPortlet (который является нашим классом портлета) в # 1, он сначала пытается найти соответствующий обработчик для запроса. Компонент типа HandlerMapping в Spring Portlet MVC помогает найти подходящий обработчик. В зависимости от того, как вы хотите выбрать обработчик / контроллер на основе запроса портлета, вы выберете соответствующий компонент HandlerMapping. В примере портлета Hello World использовался компонент PortletModeHandlerMapping (который реализует интерфейс HandlerMapping), который выбирает соответствующий обработчик / контроллер на основе текущего режима портлета в # 2. В портлете Hello World PortletModeHandlerMapping отображает режим портлета VIEW в HelloWorldController (см. Листинг 3); поэтому HelloWorldController является обработчиком для нашего запроса рендеринга, полученного на # 1 DispatcherPortlet.
Как только обработчик выбран для обработки запроса, следующим шагом является вызов соответствующего метода обработчика для выполнения обработки запроса. В листинге 1 метод handleRenderRequest обработчика отвечает за обработку запросов рендеринга, а метод handleActionRequest обрабатывает запросы действий. Запрос, полученный на # 1, является запросом рендеринга; поэтому запрос обрабатывается методом handleRenderRequest в HelloWorldController в # 3. Метод handleRenderRequest в HelloWorldController возвращает объект ModelAndView.
Следующим шагом является использование информации представления в объекте ModelAndView для получения ссылки на фактическое представление, которое является страницей JSP в случае портлета Hello World. Компонент типа ViewResolver Spring Portlet MVC помогает с разрешением представления, то есть, находит фактическое представление, соответствующее логическому имени представления. Портлет Hello World использует bean-компонент InternalResourceViewResolver (который реализует интерфейс ViewResolver) для преобразования имени представления в фактическую страницу JSP, на # 4. Как только фактическое представление разрешено ViewResolver, среда MVC Spring Portlet отправляет ссылку на представление и данные модели в сервлет ViewRenderServlet (см. Листинг 6) для визуализации представления в # 5.
Вывод
В этой статье мы создали простой портлет Hello World, используя инфраструктуру Spring 3.0 Portlet MVC. В части 2 «Аннотации Spring 3.0 Portlet MVC» мы рассмотрим, как мы можем создать многостраничный портлет, используя аннотации Spring Portlet MVC.
Нажмите здесь, чтобы получить исходный код этой статьи.