Технология Клиент-Сервер 2006'2 |
|||||||
|
Под «Web-приложениями» в J2EE обычно понимаются серверные приложения, интерфейс которых рассчитан на использование HTTP, HTML и броузеров в качестве клиентов. Вместе с тем нужно понимать, что организация Web-интерфейса – далеко не самая важная часть серверного приложения. Необходимо реализовать бизнес-логику, практически всегда необходимо интенсивно взаимодействовать с СУБД и/или унаследованными системами и т.п. Это означает, что собственно Web-часть такого приложения (реализованная в виде Web-компонентов) практически всегда – кроме самых простых случаев – работает вместе с EJB-компонентами, JMS и другими программными элементами, из которых строится сервер приложений.
В данной статье основное внимание уделяется особенностям создания Web-компонентов и организации их взаимодействия с программными компонентами прочих видов – с EJB-компонентами и коннекторами, реализующими пулы соединений с БД.
Пример простейшего приложения приводился в статье «Знакомство с IBM WebSphere Community Edition» (см. «Технология Клиент-сервер», 1’2006). В ней рассматривалась последовательность шагов, необходимых для создания WAR-архива, включения в его стандартного файла xml-дескриптора Web-приложения и JSP-документа, развертывания приложения на сервере, его запуска и обращения к нему из стандартного броузера.
В мире 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 автоматически при остановке сервера):
При редактировании параметров, например, HTTP-соединения с Tomcat (или при создании нового такого соединения) изображение на консоли будет выглядеть так:
В подкаталоге conf каталога, задаваемого файлом config.xml (в нашем случае – каталоге <install_dir>\var\catalina) находится файл web.xml, определяющий значения по умолчанию для всех параметров для web-приложений, устанавливаемых в запущенный экземпляр Tomcat. Этот файл считывается и используется до того, как будет считан и использован стандартный дескриптор WEB-INF/web.xml для Web-приложения.
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 |
Использование СУБД в 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 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-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> возникает в случае взаимодействия компонентов из различных приложений.
Структура обоих тегов очень схожа:
Отличия (помимо собственно имени тега) связаны только с дополнительной возможностью обращения к удаленным компонентам с использованием CORBA.
Остальные элементы имеют следующую структуру и возможные значения:
Структура тега <objectNameGroup> такова:
Строка, задаваемая тегом <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 ООО "К-Пресс"