Что такое JSF? Представляем JavaServer Faces

JavaServer Faces (JSF) - это стандартная технология Java для создания компонентно-ориентированных веб-интерфейсов. Подобно JavaServer Pages (JSP), JSF обеспечивает доступ к данным и логике на стороне сервера. В отличие от JSP, который по сути представляет собой HTML-страницу, наделенную серверными возможностями, JSF - это XML-документ, представляющий формальные компоненты в логическом дереве. Компоненты JSF поддерживаются объектами Java, которые не зависят от HTML и обладают полным набором возможностей Java, включая доступ к удаленным API и базам данных.

Ключевая идея такой инфраструктуры, как JSF, состоит в том, чтобы инкапсулировать (или обернуть ) клиентские технологии, такие как HTML, CSS и JavaScript, что позволяет разработчикам создавать веб-интерфейсы без особого взаимодействия с этими технологиями.

В этой статье представлен моментальный снимок подхода JSF к разработке пользовательского интерфейса на основе компонентов для веб-приложений Java. Простые примеры представляют архитектуру MVC JSF, модель событий и библиотеку компонентов. Примеры включают новые функции в JSF 2.3, и мы будем использовать PrimeFaces для нашей библиотеки компонентов.

Развитие JSF

Давно популярный, JSF недавно столкнулся с конкуренцией со стороны Java-совместимых веб-фреймворков, включая клиентские JavaScript-фреймворки. Тем не менее, JavaServer Faces остается стандартом Java, особенно для крупномасштабной корпоративной разработки на Java. Спецификация JSF также породила множество фреймворков и библиотек, которые идут в ногу с недавними улучшениями на стороне клиента. Одним из них является PrimeFaces, который мы исследуем в этом руководстве.

Хотя график будущей разработки неясен, JSF 2.3 дает разработчикам много возможностей для работы, пока мы ждем. Выпущенный в марте 2017 года, JSF 2.3 был специально разработан для модернизации JSF. Среди нескольких сотен мелких исправлений и крупных обновлений JSF 2.3 отказывается от аннотаций управляемых компонентов в пользу CDI, о чем я расскажу позже в этом руководстве.

JSF 2.3 в Джакарте EE

В сентябре 2017 года Oracle объявила о своем намерении перевести Java EE на Eclipse Foundation. С тех пор Java EE был переименован в Jakarta EE, и JSF 2.3 (Eclipse Mojarra) был принят для продолжения. Следующим крупным выпуском спецификации JSF будет Eclipse Mojarra 3.0.

Создание компонентных веб-интерфейсов в JSF

Основная идея JSF - инкапсулировать функциональность в повторно используемые компоненты. Это похоже на многоразовые теги, используемые в JSP, но компоненты JSF более формальны.

Хотя вы можете использовать страницы JSF в JavaServer Pages, чаще всего используют Facelets для создания автономных страниц JSF. Facelets - это страницы XHTML, предназначенные для определения интерфейсов JSF. С Facelets вы используете теги XML для создания дерева компонентов, которое становится каркасом для пользовательского интерфейса JSF.

В листинге 1 представлены основные части простой страницы JSF, написанной с использованием Facelets. В этом примере мы обращаемся к серверным возможностям Java через bean-компонент, который был помещен в область видимости через CDI. Позже вы узнаете больше о CDI.

Листинг 1. Пример страницы JSF.

    Hello JavaWorld!   #{javaBean.content}  

В листинге 1 мы видим стандартную страницу XHTML. Представление Facelets построено на основе XHTML. В дополнение к пространству имен XHTML определяется и используется вторичное пространство имен.

hБиблиотека содержит стандартные компоненты для использования в страницах JSF HTML. //xmlns.jcp.org/jsf/htmlБиблиотека определяет набор компонентов JSF, в этом случае набор общих HTML элементов. Один из этих компонентов - элемент.

HTML-компоненты в JSF

С точки зрения синтаксиса элемент в листинге 1 ссылается на jsf/htmlбиблиотеку с hпрефиксом. Затем он ссылается на конкретный компонент в библиотеке, который является headкомпонентом.

Компонент выводит элемент HTML - головки. (Весь этот синтаксис может показаться излишним для такой простой цели, но для этого есть веская причина, как вы вскоре увидите.)

Вложенные компоненты

Внутри головы вложен стандартный HTML- элемент. Этот элемент предоставляется компоненту вместе с вложенными в него дочерними элементами содержимого.

В теле документа выражение JSF содержится в #{}синтаксисе. Это в точности аналогично выражению JSP с ${}форматом: оно обеспечивает доступ к объектам Java в области видимости и простым функциям.

Базовый шаблон для JSF прост: используйте Facelets для построения XML-дерева, которое ссылается на библиотеку компонентов или библиотеки, затем используйте компоненты внутри библиотеки для визуализации объектов Java в формате HTML.

Использование объектов Java в JSF

Возвращаясь к листингу 1, обратите внимание, что внутри выражения JSF ( ${javaBean.content) javaBeanобъект находится в области видимости, когда выполняется эта разметка. XHTML Facelets обращается к .contentсвойству javaBeanобъекта. Конечным результатом является веб-интерфейс, который объединяет структуру представления Facelets с данными и логическими возможностями Java на стороне сервера.

Использование выражения JSF - это всего лишь один из способов доступа к данным приложения Java из пользовательского интерфейса JSF. В конце концов, вы захотите изучить другие способы взаимодействия компонента JSF с серверной частью Java - например, списки данных и сетки, а также различные элементы управления вводом. На данный момент достаточно понять, как JSF использует теги XML (или аннотации) для создания дерева компонентов, которое выводит HTML на основе данных, содержащихся в объектах Java.

Аннотации против XML

С JSF 2.3 стало возможным определять компоненты JSF с аннотациями, полностью избегая метаданных XML. Вполне возможно определить и развернуть приложение JSF без редактирования XML.

Структура приложения JSF

Подобно JavaServer Pages и Servlet API, JavaServer Faces требует стандартной структуры каталогов и метаданных. Они развертываются как файлы .war .

Структура файла .war аналогична сервлету или приложению JSP. Он содержит /web-appкаталог, в котором хранятся файлы разметки приложения (в данном случае HTML, JSP и Facelets), а также /WEB-INFкаталог, в котором представлены метаданные для описания приложения.

Обслуживание JSF

Хотя вы можете запускать JSF в контейнере Java EE, таком как Glassfish, простой контейнер сервлетов - это все, что вам действительно нужно. Tomcat - популярный контейнер для JSF и других серверных технологий Java.

JSF 2.3: спецификации и реализации

Одна из сильных сторон Java заключается в том, что она основана на стандартах, и эти стандарты регулируются процессом сообщества открытого исходного кода. С момента своего создания Java Community Process (JCP) курировал развитие технологии Java. После того, как спецификация или улучшение спецификации были разработаны и утверждены JCP, они доступны для реализации несколькими сторонами. До недавнего времени сервлеты, JSP и JSF разрабатывались с использованием процесса спецификации открытого исходного кода JCP.

Самой последней спецификацией JSF на момент написания этой статьи является JSF 2.3, выпущенная как часть Java EE 8 в 2017 году. Oracle Mojarra (теперь Eclipse) - это эталонная реализация JSF, а MyFaces и PrimeFaces - популярные сторонние реализации.

Каждая из этих платформ реализует ядро ​​JSF, которое включает некоторые стандартные компоненты. Поставщики также могут предлагать дополнительные библиотеки компонентов помимо стандартных. При оценке фреймворков JSF рекомендуется учитывать потребности вашего приложения и доступные библиотеки компонентов, которые помогут вам его создать. В идеале ваша среда JSF должна максимально приближать вас к тому, что вам нужно, прямо из коробки.

MVC в JSF 2.3

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

В реализации JSF представлением является страница Facelets с ее набором тегов XML. Они определяют макет пользовательского интерфейса. Другая половина использования JSF - это серверная часть, где классы Java поддерживают эти компоненты пользовательского интерфейса.

Управляемые bean-компоненты устарели в JSF 2.3

Аннотации управляемых бинов устарели в JSF 2.3 и заменены CDI (внедрение контекстов и зависимостей). С помощью CDI разработчики определяют контекст и внедряют объекты в этот контекст. Те, кто знаком с управляемыми компонентами, обнаружат, что синтаксис аннотаций немного отличается, но семантика остается неизменной.

Бины контроллера

В JSF 2.3 бины-контроллеры обеспечивают часть контроллера уравнения MVC. Нормальные объекты Java (часто называемые POJO или простые старые объекты Java) обеспечивают модель.

С точки зрения технологического процесса компоненты контроллера:

  1. Решите, куда направлять запросы пользователей
  2. Настройте POJO для модели
  3. Используйте модель для визуализации вида Facelets

Затем JSF сворачивает дерево компонентов и модель для визуализации выходного HTML.

В листинге 2 показано, как определить javaBeanобъект из листинга 1 с помощью CDI. В этом листинге предполагается, что в зависимостях приложения есть файл cdi-api-1.2.jar.

Листинг 2. JavaBean, определенный с помощью CDI.

 import javax.inject.Named; import javax.enterprise.context.SessionScoped; @Named @ViewScoped public class JavaBean implements Serializable { private String content = ìWelcome to JSF!î // getters/setters } 

JSF 2.3 с PrimeFaces

В следующих разделах я буду использовать PrimeFaces, чтобы показать вам, как JSF реализует шаблон MVC, управляемый событиями обмен сообщениями и повторно используемые компоненты. Для начала откройте PrimeFaces Showcase, щелкните ссылку « Данные» в левом столбце и выберите « Список данных» . Откроется демонстрационный код DataList для PrimeFaces.

На рисунке 1 показано, где найти эти образцы.

Мэтью Тайсон

На рисунке 2 показан результат простой таблицы данных, взятой из демонстрации PrimeFaces DataList.

Мэтью Тайсон

PrimeFaces DataList: доступ к модели данных

Listing 3 presents the markup for this dataList display. If you scroll to the bottom of the PrimeFaces showcase, you can see the markup in the dataList.xhtml tab.

Listing 3. Facelet for PrimeFaces DataList

   Basic  #{car.brand}, #{car.year}  

In Listing 3, notice the value property of the dataList component. You can see that this references a dataListView object, and accesses the .cars1 property on it. The component is going to use the model object returned by that field. JSF tokens use conventional accessors to reference object properties, so .cars1 will refer to the getCars() getter on the object.

Next, notice the var="car" property. This tells the dataList component what variable to use when it iterates over the list of cars returned by the value field. These properties are specific to the dataList component, but the value property is very common. The var attribute is also conventional for components that iterate over lists.

In the body of the component in Listing 3, you can see the car variable is accessed via JSF expressions like #{car.brand}. Each iteration of the dataListView.cars1 instance will output the car.brand field.

Notice that the tag demonstrates the ability to customize components for how they will display. In this case, the header is defined as Basic.

You can see how the Facelets XML will drive this output by combining the data with the markup. Now let's look at the Java code behind it.

DataList's server-side components

Listing 4 shows DataListView, the Java class that is used by the markup in Listing 3. You'll see shortly how the dataListView instance is associated with the DataListView class.

Listing 4. DataListView class

 package org.primefaces.showcase.view.data; import java.io.Serializable; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Named; // Pre JSF 2.3, this was: // import javax.faces.bean.ManagedBean; import javax.inject.Inject; import javax.faces.bean.ViewScoped; import org.primefaces.showcase.domain.Car; import org.primefaces.showcase.service.CarService; @Named @ViewScoped public class DataListView implements Serializable { private List cars1; private Car selectedCar; @Inject("#{carService}") private CarService service; @PostConstruct public void init() { cars1 = service.createCars(10); } public List getCars1() { return cars1; } public void setService(CarService service) { this.service = service; } } 

Listing 4 has a few other important elements, which we'll consider piece by piece.

Dependency injection and annotations

First, notice that the DataListView class is annotated with @Named, which you can see from the import import javax.inject.Named; is part of JSF. The @Named annotation tells JSF this bean is part of the app. The @ViewScoped annotation informs JSF that the bean will live for just the life of the view.

Затем обратите внимание, что CarServiceсвойство имеет @Injectаннотацию (называемую @ManagedPropertyдо JSF 2.3). Это еще одна функция JSF, которая позволяет «связать вместе» bean-компоненты, метод, популяризированный средой Spring и другими инструментами внедрения зависимостей. По сути, JSF найдет carServiceобъект в области видимости и автоматически свяжет его с serviceполем DataListViewобъекта.