my.life.logging.Blog

Создание портлета для Liferay с помощью Wicket. Часть 2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.

Данное руководство детально описывает процесс создания портлета для Liferay портала cредствами фреймворка Wicket.

Все части руководства:

  1. Портлетный проект для Liferay портала
  2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.
  3. Разработка функциональности Wicket-портлета
  4. Если используется Spring Framework

Исходный код разрабатываемого примера доступен на GitHub.


Изменяем файл web.xml

В моем случае SDK не создал файл web.xml в проекте портлета, хотя для Wicket он нужен. Не проблема - создадим его сами.

Основной вещью, которую необходимо будет описать в web.xml является фильтр портлета. Добавим в web.xml следующие строчки:

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
<filter>
     <filter-name>AchievementPortlet</filter-name>
     <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
     <init-param>
          <param-name>detectPortletContext</param-name>
          <param-value>true</param-value>
     </init-param>
     <init-param>
          <param-name>applicationClassName</param-name>
          <param-value>net.shafranov.portlets.achievement.AchievementPortletApp</param-value>
     </init-param>

     <!-- Возможно, другие параметры инициализации -->
     <!-- ... -->
</filter>
...

В данном случае мы просто реализуем стандартный WicketFilter. Два параметра инициализации фильтра являются обязательными.

Первый параметр detectPortletContext со значением true подскажет Wicket, что в данном случае он имеет дело именно с портлетом.

А в качестве значения второго параметра applicationClassName нужно указать имя класса приложения Wicket, которое собственно и будет являться нашим портлетом.

На первом этапе ограничимся следующей заготовкой для приложения:

AchievementPortletApp.java
1
2
3
4
5
6
7
public class AchievementPortletApp extends WebApplication {

    @Override
    public Class<? extends Page> getHomePage() {
        return AchievementHelpPage.class;
    }
}

Листинги для страницы AchievementHelpPage:

AchievementHelpPage.java
1
2
3
public class AchievementHelpPage extends WebPage {

}

AchievementHelpPage.html
1
2
3
4
5
6
7
8
9
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Achievement</title>
</head>
<body>
<div>Это портлет для показа какого-либо достижения, разработанный с помощью Apache Wicket.</div>
</body>
</html>

Соответствующий нашему фильтру <filter-mapping /> выглядит следующим образом:

web.xml
1
2
3
4
5
6
7
8
9
<filter-mapping>
    <filter-name>AchievementPortlet</filter-name>
    <url-pattern>/achievement/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

С помощью тегов мы указываем, к каким типам запросов будет иметь отношение наш фильтр. Пусть это будут все три возможных типа запросов: как прямые запросы (REQUEST), так и запросы типов FORWARD и INCLUDE.

Набор алфавитных символов в значении filter-mapping/url-pattern в случае Wicket должен совпадать с именем портлета, описанным в файле portlet.xml – в противном случае Wicket AJAX просто не будет работать. Таким образом, если в нашем случае имя портлета – “achievement”, то значение filter-mapping/url-pattern получается заключением этого имени с двух сторон в символы “/” и “/*”.
По поводу имени портлета, описанного с помощью тега <portlet-name />, смотрите следующий раздел, касающийся файла portlet.xml.

По сути, конфигурирование web.xml закончено.

Изменяем файл portlet.xml

Вторым важным конфигурационным файлом, который “решает” в случае портлетов, является portlet.xml. В WEB-INF уже имеется некоторая версия этого файла, созданная Liferay SDK. Внесем некоторые, но вполне определенные, изменения.

1. В качестве имени класса портлета указываем следующее:

portlet.xml
1
2
3
<portlet-class>org.apache.wicket.protocol.http.portlet.WicketPortlet</portlet-class>

Класс WicketPortlet вполне конкретным образом расширяет класс javax.portlet.GenericPortlet и заставляет его работать в Wicket-стиле.

2. Удаляем описание параметра view-jsp. Вместе с ним можно удалить и файл view.jsp из корня проекта.

3. Добавляем описание параметра wicketFilterPath:

portlet.xml
1
2
3
4
5
6
<init-param>
    <name>wicketFilterPath</name>
    <value>/achievement</value>
</init-param>

Значение данного параметра должно совпадать с filter-mapping/url-pattern для портлетного фильтра из web.xml, но без символов “/*” в конце.

Еще раз повторюсь, но это действительно важно. Значения трех элементов конфигурации Wicket-портлета:
1. тега <portlet-name /> из файла portlet.xml,
2. параметра инициализации wicketFilterPath из файла portlet.xml,
3. тега filter-mapping/url-pattern из файла web.xml
должны обязательно совпадать в своей алфавитной части (без учета специальных символов). То есть если значение тега <portlet-name /> – “achievement”, то значением параметра инициализации wicketFilterPath должно быть “/achievement”, а значением тега filter-mapping/url-pattern должно быть “/achievement/*”.

На этом шаге мы получим следующую конфигурацию портлета в portlet.xml:

portlet.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<portlet>
  <portlet-name>achievement</portlet-name>
  <display-name>Achievement</display-name>

  <!— То, что было добавлено нами —>
  <portlet-class>org.apache.wicket.protocol.http.portlet.WicketPortlet</portlet-class>
  <init-param>
    <name>wicketFilterPath</name>
    <value>/achievement</value>
  </init-param>
  <!————————————————–>

  <expiration-cache>0</expiration-cache>
  <supports>
    <mime-type>text/html</mime-type>
  </supports>
  <portlet-info>
    <title>Achievement</title>
    <short-title>Achievement</short-title>
    <keywords>Achievement</keywords>
  </portlet-info>
  <security-role-ref>
    <role-name>administrator</role-name>
  </security-role-ref>
  <security-role-ref>
    <role-name>guest</role-name>
  </security-role-ref>
  <security-role-ref>
    <role-name>power-user</role-name>
  </security-role-ref>
  <security-role-ref>
    <role-name>user</role-name>
  </security-role-ref>
</portlet>

Теперь портлет можно даже еще раз выложить на Liferay. Выглядеть он будет следующим образом:

Конфигурационные файлы портлета, предназначенного для Liferay

В Liferay для настройки портлетов используются еще три файла:

  • liferay-portlet.xml
  • liferay-display.xml
  • liferay-plugin-package.properties

В первом файле – liferay-portlet.xml – можно задать дополнительные свойства портлетов, которые поддерживаются только самим Liferay порталом, а не портлетной спецификацией. Например, можно указать будет ли наш портлет instanceable, что означает, что каждый экземпляр портлета, добавленный на страницу будет по сути самостоятельным портлетом, а не копией одного и того же портлета.

Для нашего примера изменять liferay-portlet.xml смысла не имеет. Поэтому перейдем к файлу liferay-display.xml.

В этом файле описывается категория, к которой будет принадлежать портлет в диалоговом окне “Add” > “More” портала. Чтобы наш портлет отображался не под категорией “Sample”, а под категорией, например, “My Wicket Portlets”, введем в этом файле следующий XML:

liferay-display.xml
1
2
3
4
5
<display>
    <category name="My Wicket Portlets">
         <portlet id="achievement" />
    </category>
</display>

Последний файл liferay-plugin-package.properties описывает плагин для внутреннего установщика Liferay портала. Одной из вещей, которую можно описать в данном файле, являются JAR-зависимости. Если плагин зависит от определенных библиотек, которые поставляются вместе с Liferay, можно указать их в данном файле, используя ключ portal.dependency.jars, и при установке необходимые JAR-ники будут скопированы в папку WEB-INF/lib внутрь плагина.

В нашем случае все зависимости проекта уже лежат в папке lib, поэтому файл liferay-plugin-package.properties будет выглядеть как-нибудь так:

liferay-plugin-package.properties
1
2
3
4
5
6
7
8
9
name=Achievement
module-group-id=liferay
module-incremental-version=1
tags=
short-description=
change-log=
page-url=http://www.shafranov.net
author=Artem Shafranov
licenses=LGPL

Comments