Вероотступник Geronimo: Использование интегрированных пакетов: GlassFish JSTL 1.2 и Apache Geronimo 2.0

JSTL и Geronimo 2.0 дают вам больше выбора, чем когда-либо, для построения Web-приложений на Java

Команда, разрабатывавшая Apache Geronimo, успешно реализовала впечатляющую новую спецификацию Java Platform, Enterprise Edition (Java EE) 5.0. Одна из многих заслуживающих внимания особенностей Java EE 5 - новая спецификация Java Standard Tag Library (JSTL) 1.2. Ключом к JSTL 1.2 является унифицированный язык выражений, который позволяет использовать лучшие свойства JSTL совместно с JavaServer Faces (JSF). В этой части освещается значимость JSTL 1.2 через призму истории Java Web-технологий и рассказывается, как команда Geronimo использовала реализацию JSTL 1.2 в GlassFish, чтобы добавить поддержку JSTL 1.2 в Geronimo.

Майкл Галпин, инженер по программному обеспечению, Vitria Technology

Майкл Галпин (Michael Galpin) имеет учёную степень по математике в Калифорнийском Технологическом институте. Он является Java-разработчиком с конца 90-х гг. и работает инженером по программному обеспечению в Vitria Technology, в Саннивейл, Калифорния.



11.07.2008

Развитие Web-технологий в Java

Платформа Enterprise Java всегда включала в себя Web-технологии. Они начинались и развивались с сервлетов.

Сервлеты

Сервлеты первоначально использовались для формирования ответов на HTTP-запросы. Написание сервлета было в общем довольно противным занятием. Взгляните на пример в листинге 1.

Листинг 1. Сервлет, генерирующий HTML
     protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
          ServletOutputStream out = response.getOutputStream();
          out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 
Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
          out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
          out.println("<head>");
          out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; 
charset=ISO-8859-1\" />");
          out.println("<title>All Users</title>");
          out.println("</head>");
          out.println("<body>");
          out.println("     <table>");
          out.println("          <tr>");
          out.println("               <td>UserID</td>");
          out.println("               <td>UserName</td>");
          out.println("               <td>Name</td>");
          out.println("          </tr>");

          UserDao dao = new UserDao();
          List users = dao.getAllUsers();
          for (int i=0;i<users.size();i++){
               User user = (User) users.get(i);
               out.println("          <tr>");
               out.println("               <td>"+user.getId()+"</td>");
               out.println("               <td>"+user.getUserName()+"</td>");
               out.println("               <td>"+user.getFirstName()+' 
'+user.getLastName()+"</td>");
               out.println("          </tr>");
          }
          out.println("     </table>");
          out.println("</body>");
          out.println("</html>");
     }

Сервлеты содержали много HTML-кода (как в примере), внедренного непосредственно в Java-код. Это делало поддержку сервлетов еще более сложной, чем разработку. Представьте, что вы хотите изменить таблицу, добавив к ней границу, в коде в листинге 1. Чтобы сделать это, придется изменять Java-код и перекомпилировать сервлет. К счастью, сервлеты были вскоре дополнены технологией JavaServer Pages (JSP).

JavaServer Pages

Технология JSP улучшила сервлеты Java. JSP-компоненты предоставили множество усовершенствований по сравнению с сервлетами, включая возможность смешивания языка разметки с Java-кодом. В листинге 2 показан тот же самый сервлет, что и в листинге 1, но с использованием JSP.

Листинг 2. JSP, версия 1.0
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="org.developerworks.*" %>
<%@ page import="java.util.List" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>All Users</title>
</head>
<body>
     <table>
          <tr>
               <td>UserID</td>
               <td>UserName</td>
               <td>Name</td>
          </tr>
          <%
               UserDao dao = new UserDao();
               List users = dao.getAllUsers();
               for (int i=0;i<users.size();i++){
                    User user = (User) users.get(i);
          %>
          <tr>
               <td><%= user.getId() %></td>
               <td><%= user.getUserName() %></td>
               <td><%= user.getFirstName() %> <%= user.getLastName() 
                 %></td>
          </tr>
          <%
               }
          %>
          </c:forEach>
     </table>
</body>
</html>

Очевидно, то, что вы видите в листинге 2, является большим шагом по сравнению с исходным сервлетом. Компоненты JSP все еще компилируются в сервлеты, но это делается контейнером сервлетов (либо это может выполняться в процессе компиляции приложения). Таким образом, JSP-компонент позволял обеспечить такую же производительность, что и сервлеты. Синтаксис JSP похож на Active Server Page (ASP) и PHP, однако компиляция в сервлеты давала JSP-страницам значительное преимущество в производительности в сравнении с другими технологиями


JSP Model 2

В коде JSP, показанном в листинге 2, все еще есть несколько значительных проблем. В нем используются скриплеты - маленькие кусочки Java-кода. Применение скриплетов представляет проблему с точки зрения как дизайна, так и практического использования. В JSP-страницах бизнес-логика (формирование списка пользователей) свободно смешивалась с отображением. Архитектура JSP Model 2 была создана для решения этой проблемы. Появилась возможность использовать сервлет совместно с JSP-страницей. Взгляните на листинг 3.

Листинг 3. Сервлет в стиле Model 2
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
        UserDao dao = new UserDao();
        List users = dao.getAllUsers();
        request.setAttribute("users", users);
        request.getRequestDispatcher("/user.jsp").forward(request, response);
    }

Сервлет может, например, производить первоначальную обработку запроса и выполнять бизнес-логику. Далее он может сохранять свои результаты в объекте HttpServletRequest и переадресовать его на страницу JSP. Это позволяет упростить JSP, как видно из листинга 4.

Листинг 4. JSP-страница в стиле Model 2
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="org.developerworks.*" %>
<%@ page import="java.util.List" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>All Users</title>
</head>
<body>
    <table>
        <tr>
            <td>UserID</td>
            <td>UserName</td>
            <td>Name</td>
        </tr>
        <%
            List users = (List) request.getAttribute("users");
            for (int i=0;i<users.size();i++){
                User user = (User) users.get(i);
        %>
        <tr>
            <td><%= user.getId() %></td>
            <td><%= user.getUserName() %></td>
            <td><%= user.getFirstName() %> <%= user.getLastName() 
   %></td>
        </tr>
        <%
            }
        %>
        </c:forEach>
    </table>
</body>
</html>

Это решает часть архитектурных проблем. Однако остается еще одна проблема практического характера. Смешивание Java-кода и HTML делает JSP-страницу сложной в разработке как для Java разработчиков, которые не знают HTML, так и для Web-дизайнеров, не знающих языка Java.

JavaServer Pages Standard Tag Library (JSTL)

Одной из целей технологии JSP стало очищение JSP от всякого Java-кода. Конечным результатом этого процесса стала спецификация JSTL. JSTL представляла собой набор тегов в HTML-стиле, вызывающих объекты Java и выполняющих многие из конструкций языка Java, в том числе перебор коллекций, условную логику и форматирование текста. JSTL позволяет JSP-компоненту развиваться, как показано в листинге 5.

Листинг 5. JSP с использованием JSTL
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>All Users</title>
</head>
<body>
     <table>
          <tr>
               <td>UserID</td>
               <td>UserName</td>
               <td>Name</td>
          </tr>
          <c:forEach items="${users}" var="user">
          <tr>
               <td><c:out value="${user.id}"/></td>
               <td><c:out value="${user.userName}"/></td>
               <td><c:out value="${user.firstName}"/> <c:out
 value="${user.lastName}"/></td>
          </tr>
          </c:forEach>
     </table>
</body>
</html>

Тег <c:forEach> позволяет обходить список пользователей. Тег <c:out> позволяет обратиться к объекту Java и вывести его данные.

Выражения, использованные в тегах, такие как ${users} и ${user.id}, интерпретируются с помощью языка выражений (JSTL Expression Language - EL). Например, EL интерпретирует строку ${users} и ищет атрибут users в различных доступных объектах, например pageContext, request, session и контекстах сервлета и приложения. ). Дальнейшим развитием JSP-страниц стала возможность использовать EL не только из тегов JSTL. Это привело к виду JSP-страницы, показанному в листинге 6.

Листинг 6. JSP с использованием JSTL и EL
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>All Users</title>
</head>
<body>
     <table>
          <tr>
               <td>UserID</td>
               <td>UserName</td>
               <td>Name</td>
          </tr>
          <c:forEach items="${users}" var="user">
          <tr>
               <td>${user.id}</td>
               <td>${user.userName}</td>
               <td>${user.firstName} ${user.lastName}</td>
          </tr>
          </c:forEach>
     </table>
</body>
</html>

Эта современная форма JSTL и EL впервые появилась в спецификации JSP 2.0. Соединенная с архитектурой Model 2 (часто реализуемой в различных средах построения пользовательского интерфейса, например Apache Struts и других), эта комбинация JSTL и EL дает возможность создавать JSP-страницы, максимально свободные от Java-кода. Это позволяет непрограммистам работать с JSP-страницами и предоставляет Java-разработчикам возможность сконцентрироваться на реализации бизнес-логики.

Технология JavaServer Faces (JSF)

Однако технология JSP - не единственная Web-технология в составе архитектуры Enterprise Java. Вскоре после выхода спецификации JSP 2.0 была представлена технология JSF. JSF изначально была создана как компонентная архитектура. Объекты на Web-странице отображаются как компоненты с жизненным циклом, с которыми связанны объекты Java. Соответственно в рассматриваемом в данной статье примере JSP-страницы вы можете связать видимые компоненты с Java-объектами, используя JSF. Результирующая JSP-страница показана в листинге 7.

Листинг 7. JSP с использованием JSF
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http:.//java.sun.com/jsf/core" prefix="f" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>All Users</title>
</head>
<body>
     <f:view>
          <h:dataTable id="users" value="#{UserBean.users}" var="user">   
            <h:column>
              <f:facet name="header">UserID</f:facet>
               <h:outputText value="#{user.id}"/>
            </h:column>
            <h:column>
              <f:facet name="header">UserName</f:facet>
               <h:outputText value="#{user.userName}"/>
            </h:column>
            <h:column>
              <f:facet name="header">Name</f:facet>
               <h:outputText value="#{user.firstName}"/> <h:outputText 
value="#{user.lastName}"/>
            </h:column>
          </h:dataTable>           
     </f:view>
</body>
</html>

Заметьте, как производится связывание таблицы dataTable с объектом Java. Теперь вы просто определяете столбцы таблицы, а итерирование по строкам компонент делает самостоятельно. Это обеспечивается с помощью управляющего компонента (UserBean), созданного с использованием ваших данных. Компонент dataTable самостоятельно выводит HTML-код, так что вам не придется писать никакого HTML-кода для таблицы. Это одно из преимуществ JSF.


JSF и JSP 1.2

JSF изначально использовала технологию JSP. Однако на момент ее создания наиболее широко используемой была версия JSP 1.2. Поэтому JSF базировалась на JSP версии 1.2 и, соответственно, не поддерживала ни JSTL, ни EL. Вы могли бы заметить использование атрибутов-значений в тегах <h:dataTable> и <h:outputText>. Они выглядят похоже на EL, используемый в JSTL. Но в JSF версии 1.0 это именно внешнее сходство. JSF поддерживает собственный EL, который работает очень похоже на EL из JSTL, позже сделанный частью технологии JSP. Однако JSF EL был несовместим со стандартным JSTL EL—до нынешнего момента.

Унифицированный язык выражений

Одним из ключевых пунктов в спецификации Java EE 5 является унифицированный язык выражений. Таким образом, EL, используемые в JSTL и JSF были объединены. Теперь можно смешивать технологии JSTL и JSF в одном файле, как показано в листинге 8.

Листинг 8. Совместное использование JSF и JSTL
     <f:view>
          <c:forEach items="${UserBean.groups}" var="group">
               ${group.groupName}
               <h:dataTable id="#{group.groupId}" value="#{group.users}" 
   var="user"> 
                 <h:column>
                   <f:facet name="header">UserID</f:facet>
                    ${user.id}
                 </h:column>
                 <h:column>
                   <f:facet name="header">UserName</f:facet>
                    ${user.userName}
                 </h:column>
                 <h:column>
                   <f:facet name="header">Name</f:facet>
                    ${user.firstName} ${user.lastName}"
                 </h:column>
               </h:dataTable>           
          </c:forEach>
     </f:view>

Пример в листинге 8 показывает обход списка групп с использованием JSTL. Теперь для каждой группы создается таблица, отображающая пользователей группы. Обратите внимание, как различные диалекты EL используются для обработки данных как в тегах JSTL (<c:forEach>), так и в выражениях EL на странице JSP, и в JSF-компонентах (<h:dataTable>). Благодаря возможности использовать смесь диалектов EL для JSTL и JSF вы получаете лучшее из обоих миров.

EL как часть платформы Java EE 5

В Java EE 5 есть еще одно значительное изменение, касающееся EL. Реализация JSTL не была обязательной частью спецификации J2EE 1.4. Разработчики Web-приложений могли выбирать, какую именно реализацию JSTL они будут использовать в своем приложении. Конечно, они могли выбрать и использование только реализации JSF для своих приложений.

Спецификация Java EE 5 требует реализации JSTL. Разработчики Web-приложений больше не обязаны беспокоиться о включении различных реализаций в свои приложения. Вместо этого они могут использовать JSTL без малейших колебаний. Кроме того, они на полную мощь могут применять JSF. Унифицированный язык выражений (EL), включенный в JSF, является частью спецификации Java EE 5.


Geronimo и реализация JSTL в GlassFish

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

Теперь, в Java EE 5, реализация JSTL устанавливается в составе сервера приложений. Таким образом, любая реализация спецификации Java EE 5 должна включать и реализацию JSTL. И когда разработчики Apache Geronimo начали работу над собственной реализацией Java EE 5 в —Geronimo 2.0—, они обязаны были добавить и реализацию JSTL.

Однако они не могли просто взять и использовать любую из существующих реализаций. Унифицированный язык выражений был одним из основных требований к реализации JSTL. Многие из JSTL-реализаций не были предназначены для работы с технологией JSF. К счастью, команде Geronimo не пришлось создавать собственный вариант JSTL и унифицированного языка выражений самостоятельно. Они могли использовать GlassFish от Sun.

Если вы не знакомы с GlassFish - это эталонная реализация спецификации Java EE 5, созданная Sun. Данное приложение построено на открытых исходных кодах и лицензировано как под Sun's Common Development and Distribution License (CDDL), так и под GNU General Public License (GPL). Sun всегда поддерживала эталонную реализацию технологии JSF, поэтому она быстро создала эталонную реализацию JSTL, включающую унифицированный язык выражений. Открытость кодов GlassFish позволила команде Geronimo использовать это достижение и включить реализацию JSTL из GlassFish в состав Geronimo 2.0. Она была добавлена в первой контрольной сборке Geronimo: Geronimo 2.0-M1.

Лицензионные соглашения

Поскольку GlassFish лицензирован и под CDDL, и под GPL, он может быть добавлен в Geronimo. Однако эта лицензия не является лицензией в стиле Apache, как у остальных составляющих Geronimo, и это накладывало некоторые ограничения на команду Geronimo.

По существу, Geronimo включает реализацию JSTL из GlassFish, однако не содержит ее исходные кодов. Далее, команда Geronimo не может менять исходных кодов, хотя она очевидно могла бы внести свой вклад в развитие JSTL в GlassFish и далее включить новый пакет в составе Geronimo.

Одна из важных особенностей Geronimo - то, что вы можете менять его код и распространять Вашу собственную, измененную версию Geronimo. Однако реализация JSTL является исключением. Ее исходный код не включен в состав Geronimo, а лицензии накладывают ограничение на распространение и изменение. Например, если вы изменили исходный код GlassFish, Ваши изменения должны быть доступны под той же самой лицензией, что и GlassFish.


Итоги

Развитие Web-технологий в Java в прошедшие годы принесло огромную выгоду разработчикам. Последний шаг в развитии - унифицированный язык выражений - обещает им дальнейшие улучшения, позволяя использовать совместно как JSTL-, так и JSF-технологии. Унифицированный язык выражений теперь стал одной из важных составных частей спецификации Java EE 5, и это делает его существенной составляющей Geronimo 2.0. Geronimo еще раз поддержал разработчиков, не только реализовав эту спецификацию, но и использовав ее эталонную реализацию. C JSTL из GlassFish и Geronimo 2.0 разработчики получают больше выбора, чем когда-либо ранее, для создания Web-приложений на Java.

Ресурсы

Научиться

Получить продукты и технологии

  • Загрузите последнюю версию Apache Geronimo.(EN)
  • Загрузите бесплатную копию сервера приложений IBM WebSphere® Application Server Community Edition - простого сервера приложений J2EE, построенного на открытых кодах Apache Geronimo и созданного, чтобы помочь вам ускорить разработку и развертывание приложений.(EN)
  • Придайте новый импульс вашему следующему проекту с открытым кодом, воспользовавшись ознакомительным ПО от IBM, которое можно загрузить через Интернет или заказать на DVD.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Технология Java, WebSphere
ArticleID=319971
ArticleTitle=Вероотступник Geronimo: Использование интегрированных пакетов: GlassFish JSTL 1.2 и Apache Geronimo 2.0
publish-date=07112008