Продолжается подписка на наши издания! Вы не забыли подписаться?

Создание Web-приложений с WAS CE

Автор: Александр Цимбал
Опубликовано: 03.07.2006

Под «Web-приложениями» в J2EE обычно понимаются серверные приложения, интерфейс которых рассчитан на использование HTTP, HTML и броузеров в качестве клиентов. Вместе с тем нужно понимать, что организация Web-интерфейса – далеко не самая важная часть серверного приложения. Необходимо реализовать бизнес-логику, практически всегда необходимо интенсивно взаимодействовать с СУБД и/или унаследованными системами и т.п. Это означает, что собственно Web-часть такого приложения (реализованная в виде Web-компонентов) практически всегда – кроме самых простых случаев – работает вместе с EJB-компонентами, JMS и другими программными элементами, из которых строится сервер приложений.

В данной статье основное внимание уделяется особенностям создания Web-компонентов и организации их взаимодействия с программными компонентами прочих видов – с EJB-компонентами и коннекторами, реализующими пулы соединений с БД.

Пример простейшего приложения приводился в статье «Знакомство с IBM WebSphere Community Edition» (см. «Технология Клиент-сервер», 1’2006). В ней рассматривалась последовательность шагов, необходимых для создания WAR-архива, включения в его стандартного файла xml-дескриптора Web-приложения и JSP-документа, развертывания приложения на сервере, его запуска и обращения к нему из стандартного броузера.

Контейнеры Web-компонентов и WAS CE

В мире open-source наиболее популярны две реализации Web-контейнеров – Tomcat и Jetty. Каждая реализация имеет свои преимущества и недостатки, сторонников и противников. К счастью, при использовании WAS CE и Geronimo право выбора остается за пользователем. Другое дело, что «реализацией по умолчанию» в Geronimo является Jetty, в WAS CE – Tomcat. В силу такого положения вещей в данной статье под Web-контейнером будем понимать Tomcat, хотя для разработчика Web-приложений J2EE разница совершенно непринципиальна.

Ниже приведен фрагмента config-файла для WAS CE. Напомним, что это файл конфигурации сервера, и пользователь, меняя параметры, определенные в этом файле (при остановленном сервере), меняет различные аспекты поведения того или иного сервиса в составе сервера.

<configuration name="geronimo/tomcat/1.0/car">
  <gbean name="TomcatResources"></gbean>
  <gbean name="TomcatEngine">
    <attribute name="initParams">name=Geronimo</attribute>
  </gbean>
  <gbean name="TomcatWebConnector">
    <attribute name="host">0.0.0.0</attribute>
    <attribute name="port">8080</attribute>
    <attribute name="redirectPort">8443</attribute>
  </gbean>
  <gbean name="TomcatAJPConnector">
    <attribute name="host">0.0.0.0</attribute>
    <attribute name="port">8009</attribute>
    <attribute name="redirectPort">8443</attribute>
  </gbean>
  <gbean name="TomcatWebSSLConnector">
    <attribute name="host">0.0.0.0</attribute>
    <attribute name="port">8443</attribute>
  </gbean>
  <gbean name="geronimo.server:J2EEApplication=null,
         J2EEModule=geronimo/tomcat/1.0/car,
         J2EEServer=geronimo,
         j2eeType=GBean,
         name=TomcatWebContainer">
    <attribute name="catalinaHome">var/catalina</attribute>
  </gbean>
</configuration>

Имя последнего компонента разбито на части для удобства восприятия на бумаге – синтаксис задания имени в стиле Geronimo требует, чтобы это была одна строка без пробелов.

Наверное, названия атрибутов компонентов GBeans, которые являются «оболочкой» реализации Web-контейнера в среде Geronimo, говорят сами за себя.

Пользователь (или администратор сервера) для изменения параметров Tomcat может использовать консоль администратора (соответствующие изменения будут занесены в файл config.xml автоматически при остановке сервера):


Рисунок 1.

При редактировании параметров, например, HTTP-соединения с Tomcat (или при создании нового такого соединения) изображение на консоли будет выглядеть так:


Рисунок 2.

В подкаталоге conf каталога, задаваемого файлом config.xml (в нашем случае – каталоге <install_dir>\var\catalina) находится файл web.xml, определяющий значения по умолчанию для всех параметров для web-приложений, устанавливаемых в запущенный экземпляр Tomcat. Этот файл считывается и используется до того, как будет считан и использован стандартный дескриптор WEB-INF/web.xml для Web-приложения.

Web-компоненты в WAS CE

Web-компоненты при работе с WAS CE создаются, развертываются на сервере и используются точно так же, как и при работе с другими J2EE-серверами. Зависимые от реализации параметры настройки компонентов помещаются в нестандартный xml-дескриптор (план развертывания, в терминах WAS CE/Geronimo).

Для самых простых Web-приложений – подобных тому, которое было рассмотрено в предыдущей статье – план развертывания не нужен совсем, вполне достаточно стандартного дескриптора J2EE. Такое приятное обстоятельство вызвано еще и тем, что сервлеты и контейнеры для работы с ними появились раньше спецификации J2EE, Web-компонентов и Web-приложений J2EE. В простейших случаях достаточно параметров и соглашений по умолчанию.

Другое дело – реальные Web-приложения, в которых web-компоненты обращаются к другим ресурсам J2EE-приложения, когда используется JNDI, когда важна последовательность загрузки конфигураций Geronimo.

Небольшая предыстория вопроса.

В Java-технологиях основным средством расширения функциональности стали сервлеты – обычные классы Java, которые должны были содержать три callback-метода с фиксированными именами и типами аргументов. Документы JSP (Java Server Pages) – по сути, те же сервлеты, просто имеющие другую форму представления. Ни о каких специальных, «стандартизованных» Web-приложениях речь не шла, как не существовало понятия «web-компонента». Реализация контейнера сервлетов, как и синтаксис обращения к сервлету, установленному в контейнере, могли быть (и были) различными для разных систем.

В спецификации сервлетов 2.3 «в хаос был внесен порядок». Сервлеты получили дескрипторы, переносимую между реализациями схему отображения логических имен на код сервлета и стали именоваться «web-компонентами». Из web-компонентов стало возможным формировать web-приложения – как совокупность логически связанных друг с другом web-компонентов и других ресурсов. Пространство ресурсов, доступных с точки зрения запущенного экземпляра web-контейнера, оказалось разбитым на подпространства – по числу установленных в контейнере web-приложений. Правда, для совместимости с «простыми сервлетами» было сохранено безымянное «web-приложение по умолчанию». Все обычные web-приложения должны иметь свои уникальные имена, и доступ к Web-компонентам по их логическим именам выполняется не в контексте экземпляра web-контейнера, а в контексте конкретного web-приложения.

Не вся необходимая для Web-приложения информация может находиться в стандартном xml-дескрипторе для web-приложения J2EE. При использовании WAS CE дополнительный дескриптор используется, например, для задания начального контекста web-приложения (по сути – имени этого Web-приложения), для управления схемой загрузки классов, для разрешения (или уточнения) ссылок на внешние ресурсы.

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

Код сервлета очень прост:

package ear_application_demo;

import javax.naming.*;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class MyServlet extends javax.servlet.http.HttpServlet 
implements javax.servlet.Servlet {

  public MyServlet() { super(); }

  public void destroy() { super.destroy(); }

  protected void doGet (
    HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();

      try 
      {
        String opString =
          request.getParameter("op1");
        int op1 = Integer.parseInt (opString);

        opString = request.getParameter("op2");
        int op2 = Integer.parseInt (opString);

        int sum = op1 + op2;
      } 
      catch (NumberFormatException e) 
      {
        ...
      }
      out.println ("<html><head><title>");
      out.println ("</title></head><body>");
      out.println ("Summa = " + sum);      
      out.println ("</body></html>");
    }

    public void init() throws ServletException 
    {
      super.init();    
    }   
}

Стандартный дескриптор Web-приложения в J2EE должен называться web.xml и находиться в каталоге WEB-INF корневого каталога WAR-архива, содержащего все Web-компоненты и другие ресурсы Web-приложения.

В нашем примере – при использовании сервлета, соответствующего спецификации версии 2.4 – текст стандартного дескриптора может выглядеть так:

<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
  <servlet>
    <description><![CDATA[This is description of my servet]]></description>
    <display-name>MyServlet</display-name>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>ear_application_demo.MyServlet</servlet-class>
    <init-param>
      <description><![CDATA[First op-erand]]></description>
      <param-name>op1</param-name>
      <param-value>0</param-value>
    </init-param>
    <init-param>
      <description><![CDATA[Second operand]]></description>
      <param-name>op2</param-name>
      <param-value>1</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping>
</web-app>

Дескриптор определяет логическое имя сервлета (тег <servlet-name>) и схему поиска его байт-кода в каталогах, находящихся под управлением контейнера сервлетов (тег <url-pattern>). Тем не менее, здесь еще не определен «начальный контекст» web-приложения, относительно которого нужно использовать указанный URL. Это будет сделано в дополнительном дескрипторе.

Помимо стандартного дескриптора, в каталоге WEB-INF WAR-архива обычно находятся подкаталоги classes и lib, которые содержат байт-код откомпилированных классов Java. В нашем случае каталог lib пуст, а каталог classes содержит подкаталог ear_application_demo (соответствующий пакету класса сервлета), в котором находится файл MyServlet.class.

Перейдем к дополнительному дескриптору. В большинстве случаев удобнее всего использовать следующий подход: файл дескриптора получает специальное имя – geronimo-web.xml – и помещается в тот же каталог WEB-INF архива Web-приложения.

Тем не менее, WAS CE предлагает альтернативные подходы. Эти подходы различны в зависимости от формата создаваемого приложения.

Простые Web-приложения – подобные рассматриваемому в данном примере – можно создавать, а затем развертывать на сервере в виде отдельного WAR-файла. В этом случае специфический для WAS CE xml-дескриптор можно назвать любым именем и хранить его в произвольном месте, не включая в состав war-архива, а при развертывании приложения на сервере просто указать это имя в командной строке, например:

java -jar " install_dir \bin\deployer.jar" --user system --password manager / 
deploy имя_файла_архива_приложения.war имя_файла_дескриптора.xml

На практике J2EE-приложения обычно включают в себя несколько модулей, т.е. JAR-, WAR- и RAR-архивов. В этом случае приложение создается в виде одного EAR-архива, который содержит все эти модули. Если по каким-то соображениям дополнительные дескрипторы WAS CE нежелательно включать в архив каждый модуля, то эти дескрипторы можно включить в сам EAR-архив. Приложение, создаваемое в виде EAR-архива, само содержит стандартный и дополнительный дескриптор (application.xml и geronimo-application.xml, соответственно). Дескрипторы application.xml и geronimo-application.xml могут для каждого модуля, для которого это необходимо, содержать тег <alt-dd> (alternative deployment descriptor), задающий имя файла соответствующего дескриптора:

Файл geronimo-application.xml:

<application
  xmlns=http://geronimo.apache.org/xml/ns/j2ee/application-1.0
  configId="MyConfigName"
  parentId="ParentConfigName">
  <module>
    <web>some-web-app.war</web>
    <alt-dd>файл_дескриптора.xml</alt-dd>
  </module>
  ...
</application>

Такой текст дескриптора EAR-приложения подразумевает, что дополнительный дескриптор для WAR-модуля, являющегося частью EAR-приложения, содержится не в самом war-архиве, а находится в корневом каталоге EAR-архива и называется файл_дескриптора.xml.

Заголовок плана развертывания (т.е. специфического для WAS CE дескриптора развертывания) имеет в общем случае следующий вид:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.0"
  xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.0"
  xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.0"
  xmlns:security="http://geronimo.apache.org/xml/ns/security-1.1"
  configId="MyConfigName"
  parentId="ParentConfigName">
  ...
</web-app>

Дополнительные пространства имен, такие, как sys, naming и security, в заголовке определять необязательно, даже если в теле дескриптора используются элементы из этих пространств – WAS CE понимает теги в «сокращенном варианте». Пространство имен указывают, если используются иные XML-анализаторы, нежели те, которые входят в состав WAS CE.

Об элементах configId и parentId уже было рассказано в статье «Знакомство с IBM WebSphere Community Edition».

Применительно к нашему примеру, специфический для WAS CE дескриптор развертывания мог бы выглядеть так:

<?xml version="1.0" encoding="ASCII"?>
<web-app xmlns=http://geronimo.apache.org/xml/ns/j2ee/web-1.0 
         configId="servlet_web_app/servlet_web_app">

  <context-root>/servlet_web_app</context-root>
  <context-priority-classloader>true</context-priority-classloader>
</web-app>

Помимо заголовка, план развертывания содержит еще два обязательных тега: тег <context-root> определяет имя web-приложения, а тег <context-priority-classloader> – схему использования загрузчиков классов. Значение false говорит о том, что контейнер должен попытаться сначала использовать загрузчик сервера и «родительских» классов в иерархии конфигураций, и только потом – загрузчик для web-приложения. О загрузчиках классов рассказывалось в статье «Знакомство с IBM WebSphere Community Edition» (см. «Клиент-сервер, 1.2006»).

Поскольку в нашем примере приложение создается в виде war-архива с именем servlet_app.war, который включает в себя все необходимое – оба дескриптора и байт-код сервлета, то развернуть его на сервере можно с помощью следующей команды:

java -jar "install_dir\bin\deployer.jar" --user system --password manager /
deploy servlet_app.war

Используя броузер в качестве клиента, обратиться к нашему сервлету для сложения чисел 23 и 45 можно так:

http://localhost:8080/servlet_web_app/MyServlet?op1=23&op2=45

Web-приложение и СУБД

Использование СУБД в WAS CE подробно рассматривалось в статье «Работа с СУБД в IBM WebSphere Community Edition». Здесь имеет смысл еще раз рассмотреть пример дополнительного дескриптора для Web-приложения, в коде которого происходит обращение к пулу соединений БД – фактически, к фабрике соединений DataSource:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://geronimo.apache.org/xml/ns/web"
  xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
  configId="webdb_app">
  <context-root>/webdb</context-root>
  <context-priority-classloader>false</context-priority-classloader>

  <naming:resource-ref>
    <naming:ref-name>jdbc/MySource</naming:ref-name>
    <naming:resource-link>MyDatabaseSource</naming:resource-link>
  </naming:resource-ref>
</web-app>

Ссылка на ресурс (реализованный в виде RAR-архива) строится с использованием двух тегов. Тег <ref-name> содержит логическое имя ресурса (фабрики соединений JDBC в данном примере), определенное в стандартном xml-дескрипторе для web-приложения. Тег <resource-link> задает зависимое от реализации имя ресурса (в нашем примере – заданное в плане развертывания пула соединений), которое сопоставляется с этим логическим именем ресурса. Этой информации достаточно, чтобы сервер WAS CE сопоставил друг с другом нужные объекты и создал динамические стабы для организации взаимодействия соответствующих компонентов GBeans.

Виды ресурсов и ссылки на них

Ссылка на ресурс, реализованный в виде RAR-файла – один из видов ссылок на ресурсы в J2EE-приложениях. WAS CE поддерживает как стандартные виды ссылок, определенные в спецификациях J2EE, так и альтернативные варианты, основанные на использовании дополнительных возможностей Geronimo/WAS CE и его сервисов.

Такими ресурсами могут быть, например, администрируемые объекты JMS (фабрики соединений, очереди и топики), EJB-компоненты в стиле спецификации EJB 2 – как с использованием локальных, так и удаленных component-интерфейсов, CORBA-объекты и другие ресурсы.

Использованию JMS и ее объектов посвящена отдельная статья. Здесь мы рассмотрим подробно ссылки на EJB-компоненты. Приложение, использующее Web- и EJB-компоненты, кратко рассматривалось в статье «Знакомство с IBM WebSphere Community Edition».

Виды обращений к EJB-компонентам можно разделить на две группы:

В случае, когда обращение выполняется в пределах одного EAR-приложения (обычная ситуация), необходимости в дополнительных указаниях, связанных с взаимодействием компонентов, не возникает. Вместо этого в стандартном xml-дескрипторе (web.xml для Web-приложений) указывается тег <ejb-link>, значение которого должно соответствовать значению тега <ejb-name> соответствующего компонента. Таким образом, вполне достаточно следующей информации в стандартных дескрипторах:

ejb-jar.xml:

<ejb-jar xmlns=http://java.sun.com/xml/ns/j2ee
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
...
  <enterprise-beans>
    <session >
      <display-name>MySSS</display-name>
      <ejb-name>MySSS</ejb-name>
      <home>ear_application.ejb.MySSSHome</home>
      <remote>ear_application.ejb.MySSS</remote>
      <local-home>
        ear_application.ejb.MySSSLocalHome
      </local-home>
      <local>ear_application.ejb.MySSSLocal</local>
      <ejb-class>ear_application.ejb.MySSSSession</ejb-class>
      <session-type>Stateless</session-type>
      ...
    </session>
  </enterprise-beans>
</ejb-jar>

web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
 ...
  <ejb-local-ref>
    <ejb-ref-name>ejb/MySSSLocal</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local-home>ear_application.ejb.MySSSLocalHome</local-home>
    <local>ear_application.ejb.MySSSLocal</local>
    <ejb-link>MySSS</ejb-link>
  </ejb-local-ref>
</web-app>

Необходимость задания дополнительной информации с использованием тегов <ejb-ref> и <ejb-local-ref> возникает в случае взаимодействия компонентов из различных приложений.

Структура обоих тегов очень схожа:



Рисунок 3.

Отличия (помимо собственно имени тега) связаны только с дополнительной возможностью обращения к удаленным компонентам с использованием CORBA.

Остальные элементы имеют следующую структуру и возможные значения:

Структура тега <objectNameGroup> такова:


Рисунок 4.

Строка, задаваемая тегом <target-name>, содержит ту же информацию, но в формате, определяемом спецификацией JSR-77. Строка не должна содержать пробелов. Вид ее (с использованием приведенных выше значений по умолчанию для домена и сервера) таков:

geronimo.server:J2EEApplication=имя_ear_приложения,J2EEModule=имя_модуля,
J2EEServer=geronimo,J2EEType=тип_компонента,name=имя_компонента

Этой информации вполне достаточно, чтобы создавать имеющие практическую ценность Web-приложения с использованием Geronimo.

Заключение

WAS CE поддерживает все возможности по созданию web-приложений, оговоренные в соответствующих спецификациях, входящих в состав J2EE. С точки зрения разработчика, работа по созданию Web-приложений с WAS CE происходит так же, как с любым другим J2EE-сервером. Для переноса приложений, написанных для других серверов, на WAS CE (или обратно) в общем случае необходимо менять только специфические для этих серверов дополнительные дескрипторы развертывания.


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

Copyright © 1994-2016 ООО "К-Пресс"