Java Server FacesПодобно Swing и AWT, JSF представляет собой каркас разработки приложений, предоставляющий набор стандартных графических компонентов для создания интерфейсов. Но при этом JSF ориентирована на создание Web-приложений.
Слайд 2
Java Server Faces Подобно Swing и AWT, JSF представляет
собой каркас разработки приложений, предоставляющий набор стандартных графических компонентов
для создания интерфейсов. Но при этом JSF ориентирована на создание Web-приложений.
Слайд 3
Компонентная архитектура JSF предоставляет описываемые тегами компоненты, соответствующие
всем полям ввода в стандартном HTML. Кроме этого можно
создавать специальные компоненты для нужд приложения. Все компоненты могут сохранять свое состояние – это поддерживается на уровне самой технологии JSF. Кроме этого компоненты используются для динамической генерации HTML-страниц. Являясь компонентной архитектурой, JSF легко расширяется и конфигурируется. Большинство функций JSF, например, навигация или управление объектами JavaBean, могут быть реализованы встраиваемыми компонентами.
Слайд 4
JSF и JSP Интерфейс JSF-приложения состоит из страниц
JSP, которые содержат компоненты, обеспечивающие функциональность интерфейса. При этом
нельзя сказать, что JSF неразрывно связана с JSP, т.к. теги, используемые на JSP-страницах всего лишь отрисовывают компоненты, обращаясь к ним по имени. Жизненный же цикл компонентов JSF не ограничивается JSP-страницей.
Слайд 5
JSF не имеет непосредственного отношения к JSP: она
лишь использует JSP через специальную библиотеку тегов – своего
рода мост. Жизненный цикл компонент JSF сильно отличается от цикла JSP-страниц.
Слайд 6
Жизненный цикл приложения JSF. Фазы жизненного цикла: 1. Восстановление представления
2. Использование параметров запроса; обработка событий 3. Проверка данных;
обработка событий 4. Обновление данных модели; обработка событий 5. Вызов приложения; обработка событий 6. Вывод результата
Слайд 7
На каждом этапе возможна обработка событий. При этом
фазы не обязательно следуют одна за другой в строго
установленном порядке. Более того, отдельные фазы можно пропускать или вовсе прерывать цикл. Таким образом, схема жизненного цикла имеет вид:
Слайд 9
Фаза 1: Восстановление представления В первой фазе обработки
— этапе восстановления представления — запрос поступает на вход
сервлета FacesServlet. Последний анализирует данные запроса и извлекает идентификатор представления, определяемый именем страницы JSP. Идентификатор используется контроллером JSP для поиска компонентов, ассоциированных с данным представлением. Если оно не существует, то контроллер создаст его, если существует - будет использовать существующее. Представление содержит в себе все необходимые компоненты графического интерфейса.
Слайд 10
Существуют три типа представлений, с которыми приходится иметь
дело на данном этапе: 1.новое 2.изначальное 3.повторное В случае нового представления JSF создает
представление страницы Faces и связывает компоненты с обработчиками событий и валидаторами данных. Затем оно сохраняется в объекте FacesContext.
Слайд 11
Этот объект служит для хранения информации, необходимой для
управления состоянием компонентов GUI в процессе обработки запросов. FacesContext
сохраняет состояние в свойстве viewRoot. Данное свойство содержит все компоненты JSF, ассоциированные с данным идентификатором представления.
Слайд 12
Изначальное представление означает, что данная страница вызывается впервые.
В этом случае JSF создает пустое представление, которое заполняется
по мере обработки JSP-страницы. Поэтому JSF сразу переходит к этапу отрисовки результата. Если пользователь возвращается на ранее уже посещенную страницу, то представление, соответствующее этой странице, уже существует и просто должно быть восстановлено. В этом случае JSF использует сохраненную информацию о состоянии представления для его воссоздания.
Слайд 13
Фаза 2: Использование данных запроса Главной задачей данного
этапа является получение данных о состоянии каждого компонента. Сами
компоненты хранятся или создаются внутри объекта FacesContext вместе со своими значениями. Значения компонентов, как правило, приходят в параметрах запроса, хотя могут извлекаться также из cookies и заголовков запроса. Многие компоненты сохраняют значения параметра запроса в свойстве submittedValue.
Слайд 14
Фаза 3: Проверка данных Конвертация и валидация данных,
как правило, выполняются в фазе проверки данных. Компонент конвертирует
и сохраняет значение свойства submittedValue. Например, если данное поле связано со свойством типа Integer, то значение будет преобразовано к типу Integer. Если конвертация проходит неудачно, создается соответствующее сообщение об ошибке, направляемое в очередь FacesContext для последующего вывода в фазе отрисовки результата.
Слайд 15
Фаза 4: Обновление модели В четвертой фазе жизненного
цикла JSF происходит обновление данных модели путем изменения свойств
серверных объектов JavaBean. Обновляются только те свойства, которые привязаны к значениям компонентов.
Слайд 16
Фаза 5: Вызов приложения В этой фазе контроллер
JSF вызывает приложение для обработки данных, полученных через форму.
Значения компонентов уже преобразованы к нужным типам, валидированы и сохранены в объектах модели. Теперь их можно использовать для выполнения бизнес-логики приложения.
Слайд 17
Фаза 6: Вывод результата В заключительной фазе цикла
происходит вывод представления вместе со всеми его компонентами и
их текущими состояниями. Теперь рассмотрим примеры JSF приложений. Пример 1. Web калькулятор. Необходимо создать Web калькулятор, который умеет выполнять простые арифметические операции. Для начала главной задачей будет создание простого Web-калькулятора, интерфейс которого представляет собой страницу, предлагающую пользователю ввести два числа для последующего сложения или умножения.
Слайд 18
Описание и отображение сервлета Faces Перед использованием Faces-сервлета необходимо
объявить его в файле web.xml
Faces Servlet
class> javax.faces.webapp.FacesServlet
Данный тег означает, что сервлет будет загружен первым 1
Слайд 19
Сервлет должен вызываться на каждый запрос со страниц
JSP, на которых используется тег . Для этого необходимо добавить
отображение сервлета (servlet mapping), указывающее, что через него должны загружаться только JSP-страницы, использующие JSF. Faces Servlet *.jsf
Faces Servlet /faces/*
Слайд 20
Согласно отображению в web.xml, JSF контейнер будет вызывать
сервлет Faces для обработки всех запросов, относительный URI которых
начинается с /faces/ или заканчивается на *.jsf. Благодаря этому будет корректно инициализироваться контекст Faces и корневой элемент представления перед показом страниц JSF. Таким образом, URL для загрузки Калькулятора должен быть либо http://localhost:8080/calculator/calculator.jsf либо http://localhost:8080/calculator/faces/calculator.jsp
Слайд 21
Создание класса Calculator Класс реализующий соответствующую бизнес логику
имеет вид: package aaa; public class Calculator{ private
int firstNumber = 0; private int result = 0; private int secondNumber = 0;
public void add(){ result = firstNumber + secondNumber; }
public void multiply() { result = firstNumber * secondNumber; }
public void clear() { result = 0; }
Слайд 22
public int getFirstNumber() { return firstNumber; }
public void setFirstNumber(int firstNumber) {
this.firstNumber = firstNumber; }
public int getResult() { return result; }
public void setResult(int result) { this.result = result; }
public int getSecondNumber() { return secondNumber; }
public void setSecondNumber(int secondNumber) { this.secondNumber = secondNumber; } }
Слайд 23
Объявление объекта Calculator в файле faces-config.xml Для объявления
управляемых объектов JavaBean служит элемент . Файл faces-config.xml имеет вид:
Слайд 24
Объявление управляемого объекта состоит из двух частей: имени
объекта — calculator —, задаваемого с помощью элемента ,
и полного имени класса (элемент ). При этом класс управляемого объекта обязан содержать конструктор без параметров. Кроме вышеперечисленных элементов существует еще один – , который определяет, где JSF будет искать объект. В данном случае это request. Т.е. область видимости запроса.
файл faces-config.xml а вместо него использовать аннотации. Т.е. в файле
calculator.java написать: @ManagedBean(name="calculator") @RequestScoped public class Calculator { ………………… }
Слайд 26
Создание страницы index.jsp Страница index.jsp необходима, чтобы гарантировать, что
calculator.jsp будет загружена в контексте JSF. Сама страница имеет
вид:
Создание страницы calculator.jsp Данная страница занимает центральное место в слое представления Калькулятора. Страница содержит элементы для ввода двух чисел. Данная страница имеет вид:
prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> Библиотека html включает в себя теги для работы с формами и другими элементами HTML. Все теги, реализующие логику, валидацию данных, контроллер и т.д., включены в библиотеку core.
Слайд 33 Если необходимо явно указать, что для работы с
элементами интерфейса будет использоваться JSF, то для этого используется
тег , информирующий JSP-контейнер о том, что компоненты будут управляться JSF. Без этого JSF не сможет построить дерево компонентов или получить доступ к ранее созданному дереву. Пример использования : ...
месте необходима форма HTML. Во время отрисовки страницы JSF
находит ранее созданные дочерние компоненты формы и вызывает их методы для генерации соответствующего HTML-кода. Тег задает метку для соответствующего поля ввода. Рссмотрим пример for="firstNumber" /> value="#{calculator.firstNumber}" />
Слайд 35
Соответствующий HTML код будет иметь вид:
value="#{userBean.user.username}" errorStyle="color:red" /> Соответствующий HTML код будет иметь вид: name="form:username" value="" /> "username": Value is required.
Слайд 37 Результаты операций сложения и умножения выводятся внутри тега
с помощью элемента . Можно свободно использовать выражения JSP
внутри . Кроме того, аналогично другим компонентам JSF этот тег содержит атрибут rendered, управляющий выводом содержимого. Таким образом, секция отображения результата выводится только если значением выражения calculator.result != 0 is является true.
Слайд 38
Развертывание и запуск приложения. Предположим, что Tomcat установлен в
папке C:\tomcat Тогда развертывание будет иметь вид: 1. Создать директорию calculator
в папке c:\tomcat\webapps\ 2. В директории calculator создать папку WEB-INF 3. В WEB-INF создать директорию classes, а в ней папку aaa 4. Скомпилировать, используя javac Calculator.java и поместить файл Calculator.class в папку c:\tomcat\webapps\calculator\WEB-INF\classes\aaa\
Слайд 39
5. Поместить файлы web.xml и faces-config.xml в каталог
файлы index.jsp и calculator.jsp в каталог c:\tomcat\webapps\calculator\ 7. Скачать пакет mojarra по адресу https://javaserverfaces.dev.java.net/ и скопировать оттуда файлы jsf-impl.jar и jsf-api.jar в каталог c:\tomcat\lib\, а также скопировать в этот же каталог пакеты jstl.jar и standard.jar. 8. Запуск приложения: http://localhost:8080/calculator/calculator.jsf Тогда в браузере получим:
Слайд 42
Компонент может содержать только дочерние компоненты, в
отличие от , и , внутрь которых можно
также помещать обычные фрагменты HTML. Данный элемент на странице включает в себя три колонки, поэтому добавление более трех дочерних компонентов приведет к появлению новой строки. Например, если написать То в браузере получим
#000 3px; width: 400px; } .resultGrid { border: solid #000 1px; width: 200px;} Применение этих стилей к имеет вид: rowClasses= "oddRow, evenRow" styleClass="formGrid"> ...
Слайд 46
Чтобы применить стили к строкам таблицы необходимо установить
значение атрибута rowClasses в oddRow, evenRow. Стиль, определяющий внешнюю
рамку для таблицы, применяется с помощью атрибута styleClass(styleClass="formGrid")
Переопределение текстов сообщений В JSF 1.2 были добавлены атрибуты requiredMessage и conversionMessage, таким образом теперь можно переопределять текст сообщений индивидуально для каждого компонента.
Слайд 50
При этом необходимо определить файл message.properties: javax.faces.component.UIInput.REQUIRED=required javax.faces.converter.IntegerConverter
.INTEGER=not a valid number При этом в теге нет необходимости писать requiredMessage, converterMessage. Файл message.properties должен находиться в директории c:\tomcat\webapps\calculator\WEB-INF\classes\
Слайд 51
Добавление контроллера Добавим метод деления в класс calculator public
class Calculator { private int firstNumber =
0; private int result = 0; ... public void divide() { this.result = this.firstNumber/this.secondNumber; } public void clear () { result = 0; } ... }
Слайд 52
Создадим класс-контроллер CalculatorController, содержащий ссылку на класс Calculator. CalculatorController
также связан с тремя компонентами JSF - другими словами,
он зависит от классов, являющихся частью JSF resultsPanel – компонент типа UIPanel firstNumberInput – компонент типа UIInput secondNumberInput – компонент типа UInput Таким образом, класс CalculatorController имеет вид:
calculator.divide(); resultsPanel.setRendered(true); facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Divided successfully", null)); }catch (Exception ex) { resultsPanel.setRendered(false); if (ex instanceof ArithmeticException) { // Т.к. поле secondNumberInput связано с полем secondNumber, то поле // secondNumber будет равно 1. secondNumberInput.setValue(Integer.valueOf(1)); } facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), null)); } return null; }
Слайд 57
public String clear() { FacesContext facesContext =
Слайд 58
public String getFirstNumberStyleClass() { if (firstNumberInput.isValid())
{ return "labelClass"; }
else { return "errorClass"; } } resultsPanel представляет собой секцию для вывода результатов арифметических операций. resultsPanel.setRendered(true) делает панель результата видимой для пользователя.
Слайд 59
JSF предоставляет средства для показа сообщений пользователям о
статусе той или иной операции. Для добавления сообщений используется
класс FacesContext, благодаря которому они впоследствии могут быть выведены с помощью тега . JSF хранит объект класса FacesContext в переменной ThreadLocal. К ней можно получить доступ, вызвав статический метод static FacesContext getCurrentInstance() getCurrentInstance(), класса FacesContext.
Слайд 60
Например, в методе add() в FacesContext добавляются сообщения,
которые должны быть доступны до конца обработки запроса. public
Слайд 61
В данном примере сообщения представляют собой объекты класса
FacesMessage, добавляемые в объект facesContext. При этом уровень важности
сообщения зависит от возникновения исключений при выполнении операции суммирования. Если оно прошло успешно, то уровень будет INFO, в противном случае – ERROR. Сообщения выводятся на странице с помощью тега : errorClass="errorClass" layout="table" globalOnly="true"/>
Слайд 62
errorClass – атрибут устанавливает CSS стиль, который будет
применяться для сообщений уровня “error”. infoClass - атрибут устанавливает CSS
стиль, который будет применяться для сообщений уровня “info”. Для вывода только глобальных сообщений, т.е. не относящихся к конкретному компоненту, можно установить значение атрибута globalOnly в true.
Слайд 63
Страница calculator.jsp будет иметь следующий вид (на этой
странице осуществляется привязка firstNumber к firstNumberInput, а также secondNumber
Слайд 70
Поскольку в данном случае объект calculator будет доступен
только через внешний объект calculatorController, его необходимо поместить в
область видимости none. Это означает, что объект не будет помещен ни в какую специальную область видимости после создания. calculator
aaa.Calculator
none
Слайд 71
Объект calculatorController будет помещен в область видимости request.
При этом ссылка на calculator будет передана в calculatorController.
Это делается с помощью выражения #{calculator} в теге . Таким образом, JSF создаст экземпляр класса Calculator и передаст его в метод setCalculator класса CalculatorController
Слайд 73
Объект calculator используется классом CalculatorController, но при этом
сам остается “чистым”, т.е. никоим образом не привязанным к
JSF. Классы модели всегда желательно держать независимыми от библиотек, подобных JSF, изолируя весь JSF-зависимый код внутри контроллера, в данном случае – классе CalculatorController. Это значительно облегчает тестирование и повторное использование модели.
Слайд 74
В случае jsf 2 можно использовать аннотации @ManagedBean(name="calculatorController") @RequestScoped public class