Фреймворк JSF

С помощью фреймворка Java™Server Faces (JSF) версии 2.2 можно легко создавать надежные Web-приложения.

Первоначальная инфраструктура релиза JSF 1 не совсем была удачной. Однако она позволила разработчикам создать на ее основе множество инновационных проектов, которые дополнили фреймворк и родилась вторая версия. Первоначально появилась инфраструктура Facelets, предлагающая замену технологии Java Server Pages (JSP). После этого была разработана Rich Faces - мощная JSF-библиотека поддержки Ajax; далее ICEFaces – новый подход к работе с Ajax в JSF, JSF Templating и т.д. Все эти проекты с открытым кодом для JSF были созданы разработчиками, которым не хватало соответствующей функциональности в JSF первой версии.

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

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

  • упрощает формирование пользовательского интерфейса из набора повторно используемых компонентов пользовательского интерфейса;
  • упрощает передачу данных приложения в пользовательский интерфейс и из него;
  • помогает управлять состоянием пользовательского интерфейса при запросах к серверу;
  • предоставляет простую модель установления связи между созданными клиентом событиями и кодом приложения на стороне сервера;
  • упрощает повторное использование компонентов пользовательского интерфейса.

Новшества фреймворка Java JSF 2.0

Фреймворк Facelets

По сравнению с предыдущей версией на смену JSP в JSF 2 пришел фреймворк Facelets, предоставляющий много мощных возможностей, помогающих создавать надежные, гибкие и расширяемые пользовательские интерфейсы. Одно из множества небольших улучшений, которые технология Facelets привнесла в JSF, является возможность помещать значения выражений JSF непосредственно в страницу XHTML. Например,

// Так было в версии JSF 1, где необходимо вывод текста оборачивать в h:outputText
<h:outputText value="#{user.name}"/>

// Так можно писать в JSF 2 непосредственно на странице
#{user.name}

Однако следует помнить, что в целях безопасности нужно всегда "экранировать" поступающий от пользователя текст. <h:outputText> экранирует текст по умолчанию.

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

Упрощение конфигурирования

Конфигурирование Java WEB приложений с помощью файла XML накладывает определенные сложности на процесс разработки, требует дополнительного контроля и подверженно ошибкам. Лучше всего делегировать процесс конфигурации инфраструктуре. Это реализовано в JSF 2 с помощью аннотаций к JavaBean компонентам.

Пример кода XML-конфигурации для JSF 1 :

<managed-bean>
    <managed-bean-name>exchangeService</managed-bean-name>
    <managed-bean-class>test.ExchangeService</managed-bean-classv
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>weatherService</managed-bean-name>
    <managed-bean-class>test.WeatherService</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

<managed-bean>
     <managed-bean-name>user</managed-bean-name>
     <managed-bean-class>test.User</managed-bean-class>
     <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Использование в JSF 2 аннотации классов вместо XML-конфигурации :

@ManagedBean(eager=true)
public class ExchangeService {
  ...
}

@ManagedBean(eager=true)
public class WeatherService {
  ...
}

@ManagedBean(name="user")
@SessionScoped
public class User {
  ...
}

По соглашению имя управляемого компонента JavaBean совпадает с именем класса, за исключением того, что первый символ приводится к нижнему регистру. Имя управляемого bean-компонента также можно указать явно с помощью атрибута name аннотации ManagedBean, например: @ManagedBean(name="user").

Для управляемых компонентов ExchangeService и WeatherService используется атрибут eager. Если атрибут eager имеет значение true, JSF создает этот управляемый bean-компонент при старте и помещает его в область видимости приложения.

Упрощение навигацией

В предыдущей версии JSF правила перехода описывались в файле конфигурации XML с помощью тегов <navigation-rule>. Например, перейти со страницы авторизации login.xhtml на страницу личного кабинета private.xhtml можно с помощью правила перехода, указанного в листинге :

<navigation-rule>
    <navigation-case>
        <from-view-id>/login.xhtml</from-view-id>
        <outcome>places</outcome>
        <to-view-id>/private.xhtml</to-view-id>
    </navigation-case>
</navigation-rule>

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

<h:commandButton id="loginButton"
  value="#{msgs.loginButtonText}"
  action="private"/>

Необходимо помнить, что файл private.xhtml должен находиться в той же директории, что и файл с кнопкой. Если имя действия не начинается с прямого слеша '/', JSF полагает, что это относительный путь. При желании можно указать абсолютный путь, как показано в следующем листинге :

<h:commandButton id="loginButton"
  value="#{msgs.loginButtonText}"
  action="/pages/private"/>

В этом случае после нажатия пользователя на кнопку JSF откроет страницу /pages/private.xhtml.

По умолчанию JSF при переходе с одной XHTML-страницы на другую использует переадресацию (forward), т.е. URL в браузере не изменится. Однако с помощью параметра faces-redirect, показанного в следующем листинге, можно делать перенаправление:

<h:commandButton id="loginButton"
  value="#{msgs.loginButtonText}"
  action="private?faces-redirect=true"/>

Управление ресурсами

JSF 2 предоставляет стандартный механизм определения ресурсов и доступа к ним. Ресурсы размещаются в директории верхнего уровня с именем resources. Единственным требованием к ресурсу является то, чтобы он находился либо в директории resources, либо в ее поддиректории. Поддиректории resources могут иметь различное наименование.

В коде страниц доступ к ресурсам осуществляется с помощью двух тегов JSF 2 : <h:outputScript> и <h:outputStylesheet>. Эти теги взаимодействуют с тегами JSF 2 <h:head> и <h:body> :

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">

  <h:head>
    ...
  </h:head>

  <h:body>
    <h:outputStylesheet library="css" name="styles.css" target="body"/>
    <h:outputScript     library="js"  name="util.js"    target="head"/>
    ...
  </h:body>
</html>

В тегах <h:outputScript> и <h:outputStylesheet> имеется два атрибута для идентификации сценария или стилей: library и name. Атрибут library определяет наименование поддиректории директории resources, где находится этот ресурс. Так файл util.js располагается в директории resources/js. Атрибут name – это имя самого ресурса.

Информация об ошибке, PROJECT_STAGE

Начиная с версии JSF 2.0 в конфигурационном файле можно определять параметр javax.faces.PROJECT_STAGE. Значение его атрибута <param-value> опеределяет параметр инициализации контекста сервлета приложения.

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

Атрибут <param-value> параметра PROJECT_STAGE может принимать следующие значения: Development (разработка), UnitTest (тестирование компонетнов), SystemTest (тестирование системы) или Production (рабочий режим). В случае ошибки при установленом значении Production на экран выводится только трассировка стека ошибки. Для вывода более подробной информации об ошибке необходимо использовать значение параметра Development.

При установленом значении Development в случае ошибки помимо трассировки стека ошибки, будет выводиться дополнительная отладочная информация, например, дерево компонентов, а также значения параметров и аттрибутов на момент ошибки (Request Parameters, Request Attributes, Session Attributes и т.д.).

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
</context-param>
  Рейтинг@Mail.ru