| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = Введение в JavaServer Faces 2.x |
| :jbake-type: tutorial |
| :jbake-tags: tutorials |
| :jbake-status: published |
| :icons: font |
| :syntax: true |
| :source-highlighter: pygments |
| :toc: left |
| :toc-title: |
| :description: Введение в JavaServer Faces 2.x - Apache NetBeans |
| :keywords: Apache NetBeans, Tutorials, Введение в JavaServer Faces 2.x |
| |
| JavaServer Faces (JSF) - это платформа разработки интерфейса пользователя для веб-приложений Java. Она призвана значительно упростить процесс создания и поддержки приложений, работающих на сервере приложений Java и визуализирующих свои пользовательские интерфейсы на целевом клиенте. JSF обеспечивает простоту использования благодаря целому ряду факторов: |
| |
| * упрощает формирование пользовательского интерфейса из набора повторно используемых компонентов пользовательского интерфейса; |
| * упрощает перенос данных приложения в пользовательский интерфейс и из него; |
| * помогает управлять состоянием пользовательского интерфейса при запросах к серверу; |
| * предоставляет простую модель установления связи между созданными клиентом событиями и кодом приложения на стороне сервера; |
| * упрощает сборку и повторное использование компонентов пользовательского интерфейса. |
| |
| Подробное описание платформы JSF приведено в link:http://docs.oracle.com/javaee/7/tutorial/doc/jsf-develop.htm[+учебном курсе по Java EE 7, Глава 12. Разработка по технологии JavaServer Faces+]. |
| |
| В этом учебном курсе описывается применение поддержки JSF 2.x к веб-приложениям с помощью IDE NetBeans. Сначала необходимо добавить поддержку платформы JSF 2.x к базовому веб-приложению, а затем приступить к выполнения следующих задач: |
| |
| * создать управляемый компонент JSF для обработки данных запроса, |
| * подключить управляемый компонент к веб-страницам приложения и |
| * преобразовать веб-страницы в файлы шаблонов Facelets. |
| |
| IDE NetBeans обеспечивает долгосрочную поддержку для JavaServer Faces. Начиная с редакции JSF 2.0 и Java EE 6, IDE NetBeans обеспечивает поддержку для JSF 2.0 и JSF 2.1. Подробнее см. в разделе link:jsf20-support.html[+Поддержка JSF 2.x в IDE NetBeans+]. |
| |
| |
| |
| image::images/netbeans-stamp-80-74-73.png[title="Содержимое этой страницы применимо к IDE NetBeans 7.2, 7.3, 7.4 и 8.0"] |
| |
| |
| Для работы с этим учебным курсом требуются программное обеспечение и материалы, перечисленные ниже. |
| |
| |=== |
| |Программное обеспечение или материал |Требуемая версия |
| |
| |link:https://netbeans.org/downloads/index.html[+IDE NetBeans+] |7.2, 7.3, 7.4, 8.0, пакет Java EE |
| |
| |link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Комплект для разработчика на языке Java (JDK)+] |7 или 8 |
| |
| |link:http://glassfish.dev.java.net/[+Сервер GlassFish+] |Open Source Edition 3.x или 4 |
| |
| |link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FjsfDemo.zip[+Проект веб-приложения `jsfDemo`+] |неприменимо |
| |=== |
| |
| *Примечания* |
| |
| * В комплект Java в среде IDE NetBeans также входит сервер GlassFish - сервер, совместимый с Java EE, который требуется для этого учебного курса. |
| * Для сравнения проекта с рабочим решением загрузите link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FjsfDemoCompleted.zip[+выполненный демонстрационный проект+]. |
| |
| |
| |
| [[support]] |
| == Добавление поддержки JSF 2.x к веб-приложениям |
| |
| Начните работу с открытия <<requiredSoftware,проекта веб-приложения `jsfDemo`>> в среде IDE. После открытия проекта в среде IDE в него можно добавить поддержку платформы с помощью окна "Свойства" в проекте. |
| |
| IDE также позволяет создавать новые проекты с поддержкой JSF 2.x. Подробнее см. раздел link:jsf20-support.html#creatingSupport[+Создание нового проекта с поддержкой JSF 2.x+]. |
| |
| 1. Нажмите кнопку 'Открыть проект' ( image:images/open-project-btn.png[] ) на главной панели инструментов IDE или нажмите Ctrl-Shift-O (⌘-Shift-O в Mac). |
| 2. В диалоговом окне "Открытие проекта" перейдите к папке на компьютере, в которой хранится разархивированный файл учебного проекта. Выберите его, а затем для открытия проекта в среде IDE нажмите кнопку "Открыть проект". |
| |
| *Примечание.* При открытии проекта NetBeans может быть отображен запрос на разрешение ссылки на библиотеки JUnit, если при установке IDE не был установлен подключаемый модуль JUnit. |
| |
| |
| [start=3] |
| . Выполните проект и посмотрите, как он выглядит в браузере. Либо щелкните правой кнопкой мыши узел проекта `jsfDemo` в окне 'Проекты' и выберите 'Запустить' или нажмите кнопку 'Запустить проект' ( image:images/run-project-btn.png[] ) на главной панели инструментов. Проект запакован и разворачивается на сервере GlassFish, а в браузере открывается страница приветствия(`index.xhtml`). |
| |
| image::images/run-project.png[title="Запустите проект, чтобы просмотреть его в браузере."] |
| |
| [start=4] |
| . Нажмите кнопку "Отправить". Страница ответа (`response.xhtml`) отображается следующим образом: |
| |
| image::images/response.png[title="Страницы приветствия и отклика в настоящее время являются статическими страницами"] |
| |
| В настоящее время страницы приветствия и отклика являются статическими, и совместно с файлом `stylesheet.css` и изображением `duke.png` они являются единственными файлами приложений, доступными из браузера. |
| |
| |
| [start=5] |
| . В окне 'Проекты' (Ctrl-1; ⌘ -1 в Mac) щелкните правой кнопкой мыши узел проекта и выберите 'Свойства', чтобы открыть окно 'Свойства проекта'. |
| |
| [start=6] |
| . Выберите категорию 'Платформы', а затем нажмите кнопку 'Добавить'. |
| |
| [start=7] |
| . Выберите 'JavaServer Faces' в диалоговом окне 'Добавление платформы'. Нажмите кнопку 'ОК'. |
| |
| image::images/add-framework.png[title="Добавление поддержки JSF к существующему проекту"] |
| |
| После выбора "JavaServer Faces" станут доступными различные параметры настройки. На вкладке 'Библиотеки' вы можете указать, как проект обращается к библиотекам JSF 2.x. Доступная версия JSF будет зависеть от версии IDE и сервера GlassFish. По умолчанию используются библиотеки, поставляемые с сервером (сервером GlassFish). Тем не менее, в IDE также входят библиотеки JSF 2.x. (Можно выбрать параметр "Зарегистрированные библиотеки", если их необходимо использовать в проекте). |
| |
| image::images/libraries-tab.png[title="Укажите доступ к библиотекам JSF 2.x"] |
| |
| [start=8] |
| . Выберите вкладку "Настройка". Можно указать способ регистрации сервлета Faces в дескрипторе развертывания проекта. Также можно указать, нужно ли в проекте использовать страницы Facelets или JSP. |
| |
| image::images/jsf-configuration.png[title="Укажите параметры сервлета Faces и предпочитаемый язык"] |
| |
| Вы также можете легко настроить проект для использования различных наборов компонентов JSF на вкладке 'Компоненты'. Чтобы использовать набор компонентов, нужно загрузить необходимые библиотеки и использовать диспетчер Ant Library для создания новой библиотеки с библиотеками наборов компонентов. |
| |
| image::images/jsf-components.png[title="Укажите параметры сервлета Faces и предпочитаемый язык"] |
| |
| [start=9] |
| . Нажмите кнопку "ОК" для подтверждения изменений и закройте окно "Свойства проекта". |
| |
| После добавления поддержки JSF к проекту дескриптор развертывания `web.xml` изменяется и выглядит следующим образом. (Изменения *выделены полужирным шрифтом*.) |
| |
| |
| [source,xml] |
| ---- |
| |
| <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> |
| *<context-param> |
| <param-name>javax.faces.PROJECT_STAGE</param-name> |
| <param-value>Development</param-value> |
| </context-param> |
| <servlet> |
| <servlet-name>Faces Servlet</servlet-name> |
| <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> |
| <load-on-startup>1</load-on-startup> |
| </servlet> |
| <servlet-mapping> |
| <servlet-name>Faces Servlet</servlet-name> |
| <url-pattern>/faces/*</url-pattern> |
| </servlet-mapping>* |
| <welcome-file-list> |
| <welcome-file>*faces/*index.xhtml</welcome-file> |
| </welcome-file-list> |
| </web-app> |
| ---- |
| |
| *Важно!* Убедитесь, что файл `web.xml` содержит только одну запись `<welcome-file>` с компонентом '`faces/`', как показано в примере. Это обеспечивает передачу страницы приветствия проекта (`index.xhtml`) через сервлет Faces перед ее отображением в браузере. Это необходимо для верного отображения компонентов библиотек тегов Facelets. |
| |
| Сервлет Faces регистрируется в проекте, и теперь страница приветствия `index.xhtml` при запросе передается через сервлет Faces. Кроме того, обратите внимание, что добавлена запись для параметра контекста `PROJECT_STAGE`. При установке значения этого параметра на "`Development`" предоставляется полезная информация во время отладки приложения. См. link:http://blogs.oracle.com/rlubke/entry/jsf_2_0_new_feature2[+http://blogs.oracle.com/rlubke/entry/jsf_2_0_new_feature2+] для получения дополнительной информации. |
| |
| Для просмотра библиотек JSF разверните узел "Библиотеки" проекта в окне "Проекты". Если используются библиотеки по умолчанию, включенные в GlassFish Server 3.1.2 или GlassFish Server 4, под узлом сервера GlassFish отображается `javax.faces.jar`. (Если вы используете старую версию GlassFish, вы увидите библиотеки `jsf-api.jar` и `jsf-impl.jar`, а не `javax.faces.jar`.) |
| |
| Поддержка JSF в среде IDE 2.x включает в себя в первую очередь большое количество мастеров для JSF, а также специальные функциональные возможности, предоставляемые редактором Facelets. Эти функциональные возможности описаны ниже. Подробнее см. в разделе link:jsf20-support.html[+Поддержка JSF 2.x в IDE NetBeans+]. |
| |
| |
| [[managedBean]] |
| == Создание управляемого компонента |
| |
| Управляемые компоненты JSF для обработки данных пользователя и сохранения их между запросами. Управляемый компонент – это link:http://en.wikipedia.org/wiki/Plain_Old_Java_Object[+POJO+] (простой объект Java), который используется для сохранения данных и управляется контейнером (например, сервером GlassFish) с помощью платформы JSF. |
| |
| Компонент POJO по существу является классом Java, который содержит публичный безаргументный конструктор и соответствует правилам присвоения имен link:http://download.oracle.com/javase/tutorial/javabeans/[+JavaBeans+] для свойств. |
| |
| При просмотре <<staticPage,статической страницы>>, полученной в результате выполнения проекта, пользователю необходим механизм, который проверяет введенное пользователем число на соответствие текущему выбранному числу и возвращает представление, соответствующее полученному результату. Чтобы создать управляемый компонент для этих целей, используйте link:jsf20-support.html#managedBean[+Мастер создания управляемого компонента+] среды IDE. Страницы Facelets, создаваемые в следующем разделе, должны иметь доступ к числу, вводимому пользователем, и к сгенерированному ответу. Для упрощения добавьте свойства `userNumber` и `response` к управляемому компоненту. |
| |
| * <<usingManagedBean,Использование мастера создания управляемого компонента>> |
| * <<creatingConstructor,Создание конструктора>> |
| * <<addingProperties,Добавление свойств>> |
| |
| |
| [[usingManagedBean]] |
| === Использование мастера создания управляемого компонента |
| |
| 1. В окне 'Проекты' щелкните правой кнопкой мыши узел проекта `jsfDemo` и выберите 'Создать' > 'Управляемый компонент JSF'. (Если "Управляемый компонент" отсутствует, выберите "Другие". Затем выберите параметр "Управляемый компонент JSF" в категории "JavaServer Faces". Нажмите кнопку "Далее". |
| 2. В мастере введите следующее: |
| * *Имя класса:* UserNumberBean; |
| * *Пакет:* guessNumber; |
| * *Имя:* UserNumberBean |
| * *Контекст:* сеанс |
| |
| image::images/managed-bean.png[title="Используйте мастер управляемых компонентов JSF для создания нового управляемого компонента"] |
| |
| [start=3] |
| . Нажмите кнопку "Завершить". Класс `UserNumberBean` будет создан и открыт в редакторе. Обратите внимание на следующие аннотации (*выделено полужирным шрифтом*): |
| |
| [source,java] |
| ---- |
| |
| package guessNumber; |
| |
| import javax.faces.bean.ManagedBean; |
| import javax.faces.bean.SessionScoped; |
| |
| /** |
| * |
| * @author nbuser |
| */ |
| *@ManagedBean(name="UserNumberBean") |
| @SessionScoped* |
| public class UserNumberBean { |
| |
| /** Creates a new instance of UserNumberBean */ |
| public UserNumberBean() { |
| } |
| |
| } |
| ---- |
| |
| Поскольку вы используете JSF 2.x, можно объявить все относящиеся к JSF компоненты с помощью аннотаций. В предыдущих версиях их необходимо было объявлять в файле настройки Faces (`faces-config.xml`). |
| |
| [tips]#Для просмотра документации Javadoc по всем аннотациям JSF 2.1 обратитесь к link:http://javaserverfaces.java.net/nonav/docs/2.1/managed-bean-javadocs/index.html[+Спецификации аннотации управляемого компонента Faces+].# |
| |
| |
| [[creatingConstructor]] |
| === Создание конструктора |
| |
| Конструктор `UserNumberBean` должен создавать случайное число от 0 до 10 и сохранять его в переменной экземпляра. Таким образом частично формируется бизнес-логика для приложения. |
| |
| 1. Определите конструктор для класса `UserNumberBean`. Введите следующий код (изменения выделены *полужирным шрифтом*). |
| |
| [source,java] |
| ---- |
| |
| public class UserNumberBean { |
| |
| *Integer randomInt;* |
| |
| /** Creates a new instance of UserNumberBean */ |
| public UserNumberBean() { |
| *link:http://docs.oracle.com/javase/7/docs/api/java/util/Random.html[+Random+] randomGR = new Random(); |
| randomInt = new Integer(randomGR.link:http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29[+nextInt+](10)); |
| System.out.println("Duke's number: " + randomInt);* |
| } |
| |
| } |
| ---- |
| |
| Вышеуказанный код создает случайное число от 0 до 10 и записывает это число в протокол сервера. |
| |
| |
| [start=2] |
| . Исправьте операторы импорта. Для этого щелкните метку4 подсказки ( image:images/hint-icon.png[] ), которая отображается на левой границе редактора, затем выберите параметр для импорта `java.util.Random` в класс. |
| |
| [start=3] |
| . Повторно запустите проект (нажмите кнопку 'Запустить проект' ( image:images/run-project-btn.png[] ) или нажмите F6; fn-F6 в Mac). При выполнении проекта файл протокола сервера автоматически открывается в окне вывода. |
| |
| image::images/output1.png[title="Файл журнала сервера автоматически открывается в окне вывода."] |
| |
| Обратите внимание на то, что в окне вывода не отображается "`Номер Дюка: `" (как указывалось в конструкторе). Объект `UserNumberBean` не создан, так как по умолчанию в JSF используется _"ленивое" создание экземпляра_. Таким образом, компоненты в определенных контекстах создаются и инициализируются, только если они необходимы в приложении. |
| |
| Состояния link:http://javaserverfaces.java.net/nonav/docs/2.1/managed-bean-javadocs/index.html[+Документации Javadoc по аннотации `@ManagedBean`+]: |
| |
| _Если атрибут `eager()` имеет значение `true`, а значением `managed-bean-scope` является "application", то в среде выполнения при запуске приложения должен быть создан экземпляр этого класса. Создание и сохранение экземпляра должно осуществляться до обслуживания запросов. Если атрибут _eager_ не указан либо имеет значение `false` или элементу `managed-bean-scope` не присвоено значение "приложение", по умолчанию происходит "ленивое" создание экземпляра и контекстное сохранение управляемого компонента._ |
| |
| [start=4] |
| . Поскольку класс `UserNumberBean` входит в контекст сеанса, реализуется интерфейс `Serializable`. |
| |
| [source,java] |
| ---- |
| |
| @ManagedBean(name="UserNumberBean") |
| @SessionScoped |
| public class UserNumberBean *implements Serializable* { |
| ---- |
| Используйте метку подсказки ( image:images/hint-icon.png[] ) для импорта `java.io.Serializable` в класс. |
| |
| |
| [[addingProperties]] |
| === Добавление свойств |
| |
| Страницы Facelets, создаваемые в следующем разделе, должны иметь доступ к числу, вводимому пользователем, и к сгенерированному ответу. Для упрощения этого добавьте свойства `userNumber` и `response` к классу. |
| |
| 1. Начните с объявления `Integer` с именем `userNumber`. |
| |
| [source,java] |
| ---- |
| |
| @ManagedBean(name="UserNumberBean") |
| @SessionScoped |
| public class UserNumberBean implements Serializable { |
| |
| Integer randomInt; |
| *Integer userNumber;* |
| ---- |
| |
| [start=2] |
| . Щелкните правой кнопкой мыши в редакторе и выберите команду "Вставить код" (ALT+INS; CTRL+I на компьютере Mac). Выберите методы получения и установки. |
| |
| image::images/getter-setter.png[title="Используйте IDE для создания методов доступа для свойств"] |
| |
| [start=3] |
| . Выберите параметр `userNumber`: `Integer`. Нажмите кнопку "Создать". |
| |
| image::images/generate-getters-setters.png[title="Используйте IDE для создания методов доступа для свойств"] |
| |
| Обратите внимание на то, что методы `getUserNumber()` и `setUserNumber(Integer userNumber)` добавлены в класс. |
| |
| |
| [start=4] |
| . Создайте свойство `response`. Объявите `String` с именем `response`. |
| |
| [source,java] |
| ---- |
| |
| @ManagedBean(name="UserNumberBean") |
| @SessionScoped |
| public class UserNumberBean implements Serializable { |
| |
| Integer randomInt; |
| Integer userNumber; |
| *String response;* |
| ---- |
| |
| [start=5] |
| . Создайте метод получения для `response`. (Для этого приложения не требуется метод установки). Для создания кода шаблона в среде IDE можно использовать всплывающее окно "Создание кода", упомянутое выше в действии 2. Однако в целях изучения данного руководства просто вставьте нижеуказанный метод в класс. |
| |
| [source,html] |
| ---- |
| |
| public String getResponse() { |
| if ((userNumber != null) && (userNumber.link:http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#compareTo(java.lang.Integer)[+compareTo+](randomInt) == 0)) { |
| |
| //invalidate user session |
| FacesContext context = FacesContext.getCurrentInstance(); |
| HttpSession session = (HttpSession) context.getExternalContext().getSession(false); |
| session.invalidate(); |
| |
| return "Yay! You got it!"; |
| } else { |
| |
| return "<p>Sorry, " + userNumber + " isn't it.</p>" |
| + "<p>Guess again...</p>"; |
| } |
| } |
| ---- |
| Вышеуказанный метод выполняет две функции. |
| 1. Тестирует введенное пользователем число (`userNumber`) на равенство случайному числу, сгенерированному для сеанса (`randomInt`), и возвращает соответствующий ответ `String`. |
| 2. Определяет пользовательский сеанс как недействительный, если пользователь ввел правильное число (т.е., если `userNumber` равно `randomInt`). Это необходимо для того, чтобы новое сгенерированное число побудило пользователя сыграть еще раз. |
| |
| [start=6] |
| . Щелкните правой кнопкой мыши в области редактора и выберите команду "Исправить операторы импорта" (ALT+SHIFT+I; &#8984+SHIFT+I на компьютере Mac). Параметры импорта автоматически создаются для: |
| * `javax.servlet.http.HttpSession` |
| * `javax.faces.context.FacesContext` |
| |
| Можно нажать сочетание клавиш CTRL+ПРОБЕЛ на элементах в редакторе для вызова предложений автозавершения кода и поддержки документации. Нажмите сочетание клавиш CTRL+ПРОБЕЛ, установив курсор на `FacesContext`, для просмотра описания класса из документации Javadoc. |
| |
| |
| image::images/documentation-support.png[title="Для вызова поддержки автозавершения кода и документации нажмите сочетание клавиш CTRL+ПРОБЕЛ."] |
| |
| Щелкните значок веб-браузера ( image:images/web-browser-icon.png[] ) в окне документации, чтобы открыть Javadoc во внешнем веб-браузере. |
| |
| |
| |
| [[wire]] |
| == Установление связи между управляемым компонентом и страницами |
| |
| Одной из первичных целей JSF является отмена необходимости записывать шаблонный код для управления объектами <<pojo,POJO>> и их взаимодействием с видами приложений. Пример этого был приведен в предыдущем разделе, в котором JSF создал объект `UserNumberBean` при выполнении приложения. Это представление называется link:http://martinfowler.com/articles/injection.html[+Инверсия управления+] (IoC). Оно позволяет контейнеру принимать на себя ответственность за управление частями приложения, иначе разработчику потребовалось бы написать код с повторениями. |
| |
| В предыдущем разделе был создан управляемый компонент, генерирующий случайное число от 0 до 10. Также было создано два свойства `userNumber` и `response`, представляющие соответственно пользовательский ввод числа и ответ на вопрос пользователя. |
| |
| В этом разделе показаны способы использования `UserNumberBean` и его свойств на веб-страницах. JSF позволяет это сделать с помощью языка выражения. Язык выражения используется для привязки значений свойств к компонентам пользовательского интерфейса JSF, содержащихся на веб-страницах приложений. В этом разделе также показано, как можно воспользоваться внутренними функциями навигации JSF 2.x для перемещения между индексом и страницами ответов. |
| |
| Эта поддержка в среде IDE обеспечивается с помощью функции автозавершения кода и средств документации, которые вызываются нажатием сочетания клавиш CTRL+ПРОБЕЛ, когда курсор установлен на каком-либо элементе в редакторе. |
| |
| Начните с внесения изменений в `index.xhtml`, затем измените `response.xhtml`. На обеих страницах замените элементы формы HTML их эквивалентами JSF, поскольку они определены в link:http://javaserverfaces.java.net/nonav/docs/2.1/vdldocs/facelets/index.html[+библиотеке тегов HTML для JSF+]. Затем используйте язык выражений JSF для привязки значений свойств к выбранным компонентам пользовательского интерфейса. |
| |
| * <<index,index.xhtml>> |
| * <<response,response.xhtml>> |
| |
| |
| [[index]] |
| === index.xhtml |
| |
| 1. Откройте страницу `index.xhtml` в редакторе. Дважды щелкните узел `index.xhtml` в окне "Проекты" или нажмите сочетание клавиш ALT+SHIFT+O для открытия диалогового окна "Переход к файлу". |
| |
| Как индекс, так и страницы ответов уже содержат компоненты пользовательского интерфейса JSF, необходимые для этого упражнения. Просто раскомментируйте их и закомментируйте элементы HTML, используемые в настоящий момент. |
| |
| [start=2] |
| . Закомментируйте элемент формы HTML. Для этого выделите элемент формы HTML, как показано на изображении ниже, затем нажмите CTRL+/ (&#8984+/ на компьютере Mac). |
| |
| *Примечание. *Для выделения воспользуйтесь функцией перетаскивания в редакторе с помощью мыши или с помощью клавиатуры удерживайте клавишу Shift и используйте клавиши со стрелками. |
| |
| image::images/comment-out.png[title="Выделите код, затем нажмите Ctrl-/ для закомментирования кода"] |
| |
| Для переключения комментариев нажмите сочетание клавиш CTRL+/ (&#8984+/ на компьютере Mac). Эту комбинацию клавиш также можно использовать для других типов файлов, например, Java и CSS. |
| |
| |
| [start=3] |
| . Раскомментируйте компонент формы HTML для JSF. Выделите этот компонент, как показано на рисунке ниже, затем нажмите CTRL+/ (&#8984+/ на компьютере Mac). |
| |
| *Примечание.* Возможно, вам придется нажать Ctrl-/ дважды, чтобы раскомментировать код. |
| |
| |
| image::images/comment.png[title="Выделите закомментированный код, затем нажмите Ctrl-/ для удаления комментария"] |
| |
| После того как компонент формы HTML для JSF раскомментирован, в редакторе будет указано, что теги `<h:form>`, `<h:inputText>` и `<h:commandButton>` не объявлены. |
| |
| image::images/undeclared-component.png[title="Редактор обеспечивает сообщения об ошибках для необъявленных компонентов"] |
| |
| [start=4] |
| . Для объявления этих компонентов используйте автозавершение кода IDE, чтобы добавить пространство имен библиотеки тегов в тег `<html>` страницы. Наведите курсор на любой из необъявленных тегов, нажмите Alt-Enter и нажмите Enter, чтобы добавить предложенные библиотеки тегов. (При наличии нескольких параметров перед нажатием клавиши ВВОД убедитесь, что выбран тег, отображаемый в редакторе.) Пространство имен библиотеки тегов HTML для JSF добавляется к тегу `<html>` (*выделено ниже полужирным шрифтом*), и указания на ошибки исчезают. |
| |
| *Примечание.* Если в IDE нет возможности добавить библиотеку тегов, потребуется вручную изменить элемент ``<html>`` . |
| |
| |
| [source,java] |
| ---- |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" |
| *xmlns:h="http://xmlns.jcp.org/jsf/html"*> |
| ---- |
| |
| [start=5] |
| . Используйте язык выражения JSF для привязки свойства `userNumber` для `UserNumberBean` к компоненту `inputText`. Атрибут `value` используется для указания текущего значения визуализируемого компонента. Введите в код, отображаемый ниже *полужирным шрифтом*. |
| |
| [source,java] |
| ---- |
| |
| <h:form> |
| <h:inputText id="userNumber" size="2" maxlength="2" *value="#{UserNumberBean.userNumber}"* /> |
| ---- |
| |
| В языке выражения JSF используется синтаксис `#{}`. Внутри этих парных символов указывается имя требуемого управляемого компонента и его свойство, разделенные точкой (`.`). Теперь при отправке данных формы на сервер значение автоматически сохраняется в свойстве `userNumber` с помощью метода установки свойств (`setUserNumber()`). Кроме того, если страница запрошена и значение для `userNumber` уже установлено, значение автоматически отображается в визуализированном компоненте `inputText`. Дополнительные сведения приведены в link:http://docs.oracle.com/javaee/7/tutorial/doc/jsf-develop001.htm#BNAQP[+Руководстве по Java EE 7. Глава 12.1.2 Использование языка выражений для создания ссылок на управляемые сеансные объекты+]. |
| |
| |
| [start=6] |
| . Укажите адресата для запроса, который вызывается при нажатии кнопки формы. В HTML-версии формы это возможно выполнить с помощью атрибута `action` тега `<form>`. С помощью JSF можно использовать атрибут `action` для `commandButton`. Кроме того, благодаря внутренней функции навигации JSF 2.x вам нужно только указать имя конечного файла без расширения. |
| |
| Введите код, отображаемый ниже *полужирным шрифтом*. |
| |
| |
| [source,xml] |
| ---- |
| |
| <h:form> |
| <h:inputText id="userNumber" size="2" maxlength="2" value="#{UserNumberBean.userNumber}" /> |
| <h:commandButton id="submit" value="submit" *action="response"* /> |
| </h:form> |
| ---- |
| |
| В среде выполнения JSF осуществляется поиск файла с именем `response`. Предполагается, что расширение файла такое же, как у файла, из которого произошел запрос (`index*.xhtml*`), и поиск файла `response.xhtml` выполняется в папке исходного файла (т.е. в корневом веб-узле). |
| |
| *Примечание. *JSF 2.x позволяет упростить разработку. При использовании JSF 1.2 для этого проекта необходимо объявить правило перехода в файле настройки Faces. Объявление правила может выглядеть следующим образом: |
| |
| |
| [source,xml] |
| ---- |
| |
| <navigation-rule> |
| <from-view-id>/index.xhtml</from-view-id> |
| |
| <navigation-case> |
| <from-outcome>response</from-outcome> |
| <to-view-id>/response.xhtml</to-view-id> |
| </navigation-case> |
| </navigation-rule> |
| ---- |
| |
| Нижеприведенные действия с 7 по 12 являются дополнительными. Если необходимо выполнить быструю сборку проекта, сразу перейдите к <<response,`response.xhtml`>>. |
| |
| |
| [start=7] |
| . Протестируйте, выполняется ли вызов метода `setUserNumber()` вышеуказанным выражением на языке выражения при обработке запроса. Для выполнения этого используйте отладчик Java среды IDE. |
| |
| Переключите на класс `UserNumberBean` (нажмите сочетание клавиш CTRL+TAB и выберите из списка файл). Установите точку останова в сигнатуре метода `setUserNumber()`. Это можно сделать, щелкнув мышкой в области левого поля. Появится красный значок, указывающий, что точка останова метода установлена. |
| |
| image::images/set-breakpoint.png[title="Щелкните левую границу редактора для задания точек останова"] |
| |
| [start=8] |
| . Нажмите кнопку 'Отладка проекта' (image:images/breakpoint-btn.png[]) на главной панели инструментов IDE. Начинается сеанс отладки, и в браузере открывается страница приветствия проекта. |
| |
| *Примечания.* |
| |
| * Вам может быть предложено подтвердить порт сервера для отладки приложений. |
| * Если появится диалоговое окно 'Отладить проект', выберите опцию по умолчанию 'Java на стороне сервера' и нажмите кнопку 'Отладка'. |
| |
| [start=9] |
| . В браузере введите номер в форму и нажмите кнопку "Отправить". |
| |
| [start=10] |
| . Вернитесь в среду IDE и проверьте класс `UserNumberBean`. Отладчик приостановлен в методе `setUserNumber()`. |
| |
| image::images/debugger-suspended.png[title="Выполняется приостановка отладчика в соответствии с точками останова"] |
| |
| [start=11] |
| . Откройте окно "Переменные отладчика" (выберите "Окно" > "Отладка > "Переменные" или нажмите сочетание клавиш CTRL+SHIFT+1). На экран будут выведены значения переменных для точки, в которой приостановлен отладчик. |
| |
| image::images/variables-window.png[title="Отслеживание значений переменных с помощью окна 'Переменные отладчика'"] |
| |
| На приведенном выше изображении значение "`4`" предоставлено для переменной `userNumber` в сигнатуре `setUserNumber()`. (Число 4 введено в форму.) "`this`" относится к объекту `UserNumberBean`, созданному для пользовательского сеанса. Далее можно отметить, что значение свойства `userNumber` в настоящий момент равно `null`. |
| |
| |
| [start=12] |
| . На панели отладчика нажмите кнопку 'Вход в' ( image:images/step-into-btn.png[] ). Отладчик выполняет обработку строки, на которой он в настоящий момент приостановлен. Происходит обновление окна "Переменные" с указанием выполненных изменений. |
| |
| image::images/variables-window2.png[title="Окно переменных обновляется при переходе по коду"] |
| |
| Теперь свойству `userNumber` присвоено значение, введенное в форме. |
| |
| |
| [start=13] |
| . Выберите Отладка> Завершить сеанс отладки (Shift-F5; Shift-Fn-F5 на Mac) из главного меню, чтобы остановить отладчик. |
| |
| |
| [[response]] |
| === response.xhtml |
| |
| 1. Откройте страницу `response.xhtml` в редакторе. В окне "Проекты" дважды щелкните узел `response.xhtml` или нажмите сочетание клавиш ALT+SHIFT+O для открытия диалогового окна "Переход к файлу". |
| 2. Закомментируйте элемент формы HTML. Выделите открывающий и закрывающий теги HTML `<form>` и код между ними, затем нажмите CTRL+/ (&#8984+/ на компьютере Mac). |
| |
| *Примечание: * Для выделения воспользуйтесь функцией перетаскивания в редакторе с помощью мыши или с помощью клавиатуры удерживайте клавишу Shift и используйте клавиши со стрелками. |
| |
| |
| [start=3] |
| . Раскомментируйте компонент формы HTML для JSF. Выделите открывающий и закрывающий теги `<h:form>` и код между ними, затем нажмите CTRL+/ (&#8984+/ на компьютере Mac). |
| |
| На данном этапе, код между тегами `<body>` выглядит следующим образом: |
| |
| |
| [source,html] |
| ---- |
| |
| <body> |
| <div id="mainContainer"> |
| |
| <div id="left" class="subContainer greyBox"> |
| |
| <h4>[ response here ]</h4> |
| |
| <!--<form action="index.xhtml"> |
| |
| <input type="submit" id="backButton" value="Back"/> |
| |
| </form>--> |
| |
| <h:form> |
| |
| <h:commandButton id="backButton" value="Back" /> |
| |
| </h:form> |
| |
| </div> |
| |
| <div id="right" class="subContainer"> |
| |
| <img src="duke.png" alt="Duke waving" /> |
| <!--<h:graphicImage url="/duke.png" alt="Duke waving" />--> |
| |
| </div> |
| </div> |
| </body> |
| ---- |
| |
| После того как компонент формы HTML для JSF раскомментирован, в редакторе будет указано, что теги `<h:form>` и `<h:commandButton>` не объявлены. |
| |
| |
| [start=4] |
| . Для объявления этих компонентов используйте автозавершение кода IDE, чтобы добавить пространство имен библиотеки тегов в тег `<html>` страницы. |
| |
| Используйте поддержку автозавершения кода в редакторе для добавления необходимых пространств имен JSF к файлу. При выборе тега JSF или Facelets через автозавершение кода происходит автоматическое добавление требуемого пространства имен к корневому элементу документа. Подробнее см. в разделе link:jsf20-support.html#facelets[+Поддержка JSF 2.x в IDE NetBeans+]. |
| |
| Установите курсор на один из необъявленных тегов и нажмите сочетание клавиш CTRL+ПРОБЕЛ. Предложения автозавершения кода и отображения поддержки документации. |
| |
| image::images/code-completion2.png[title="Для вызова рекомендаций по автозавершению кода и всплывающего окна документации"] |
| |
| Нажмите ENTER. (При наличии нескольких параметров перед нажатием клавиши ВВОД убедитесь, что выбран тег, отображаемый в редакторе.) Пространство имен библиотеки тегов HTML для JSF добавляется к тегу `<html>` (*выделено ниже полужирным шрифтом*), и указания на ошибки исчезают. |
| |
| |
| [source,java] |
| ---- |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" |
| *xmlns:h="http://xmlns.jcp.org/jsf/html"*> |
| ---- |
| |
| [start=5] |
| . Укажите адресата для запроса, который вызывается при нажатии пользователем кнопки формы. Кнопку необходимо установить так, чтобы при ее нажатии пользователь возвращался на страницу-указатель. Для этого следует использовать атрибут `action` для `commandButton`. Введите в код, отображаемый *полужирным шрифтом*. |
| |
| [source,xml] |
| ---- |
| |
| <h:form> |
| |
| <h:commandButton id="backButton" value="Back" *action="index"* /> |
| |
| </h:form> |
| ---- |
| |
| *Примечание. * При вводе `action="index"` пользователи в работе зависят от функции явной навигации в JSF. При нажатии кнопки формы в среде выполнения JSF осуществляется поиск файла с именем `index`. Предполагается, что расширение файла такое же, как у файла, от которого был направлен запрос (`response*.xhtml*`), и поиск файла `index.xhtml` выполняется в папке исходного файла (т.е. в корневом веб-узле). |
| |
| |
| [start=6] |
| . Замените статический текст "[здесь ответ]" значением свойства `response` для `UserNumberBean`. Для этого используйте язык выражения JSF. Введите следующее (*выделено полужирным шрифтом*). |
| |
| [source,html] |
| ---- |
| |
| <div id="left" class="subContainer greyBox"> |
| |
| <h4>*<h:outputText value="#{UserNumberBean.response}"/>*</h4> |
| ---- |
| |
| [start=7] |
| . Запустите проект (нажмите кнопку 'Запустить проект' ( image:images/run-project-btn.png[] ) или нажмите F6; fn-F6 в Mac). При появлении в браузере страницы приветствия введите номер и нажмите `submit`. Страница ответа будет отображаться следующим образом (выводится на экран, если введен неправильный номер). |
| |
| image::images/response2.png[title="Просмотрит текущее состояния проекта в браузере"] |
| |
| Две ошибки в текущем состоянии страницы ответа: |
| |
| 1. Теги HTML `<p>` отображаются в ответном сообщении. |
| 2. Кнопка "Назад" не отображается в правильном местоположении. (Сравните с <<originalVersion,исходной версией>>.) |
| |
| При выполнении следующих двух шагов эти ошибки устраняются. |
| |
| |
| [start=8] |
| . Установите атрибут `escape` тега `<h:outputText>` на `false`. Установите курсор между `outputText` и `value`, вставьте пробел и нажмите сочетание клавиш CTRL+ПРОБЕЛ для вызова автозавершения кода. Прокрутите вниз для выбора атрибута `escape` и проверки документации. |
| |
| image::images/escape-false.png[title="Нажмите Ctrl-Пробел для просмотра возможных значений атрибутов и документации"] |
| |
| Как указано в документации, значение `escape` установлено по умолчанию на `true`. Это означает, что символы, которые стандартно анализируются как html, включены в строку, как указано выше. Установка значения на `false` означает, что символы, анализируемые как HTML, можно визуализировать как HTML. |
| |
| Нажмите ENTER, затем в качестве значения введите `false`. |
| |
| |
| [source,xml] |
| ---- |
| |
| <h4><h:outputText *escape="false"* value="#{UserNumberBean.response}"/></h4> |
| ---- |
| |
| [start=9] |
| . Установите атрибут `prependId` тега `<h:form>` на `false`. Установите курсор сразу после "`m`" в `<h:form>` и вставьте пробел, затем нажмите сочетание клавиш CTRL+ПРОБЕЛ для вызова автозавершения кода. Прокрутите вниз для выбора атрибута `prependId` и проверки документации. Затем нажмите ENTER и в качестве значения введите `false`. |
| |
| [source,java] |
| ---- |
| |
| <h:form *prependId="false"*> |
| ---- |
| |
| В JSF применяются внутренние идентификаторы для отслеживания компонентов пользовательского интерфейса. В текущем примере при проверке исходного кода визуализируемой страницы отображается следующее: |
| |
| |
| [source,xml] |
| ---- |
| |
| <form id="j_idt5" name="j_idt5" method="post" action="/jsfDemo/faces/response.xhtml" enctype="application/x-www-form-urlencoded"> |
| <input type="hidden" name="j_idt5" value="j_idt5" /> |
| <input *id="j_idt5:backButton"* type="submit" name="j_idt5:backButton" value="Back" /> |
| <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="7464469350430442643:-8628336969383888926" autocomplete="off" /> |
| </form> |
| ---- |
| |
| Идентификатором элемента формы является `j_idt5`, и этот идентификатор _предшествует_ идентификатору кнопки "Назад", включенной в форму (*выделено полужирным шрифтом* в приведенном выше примере). Поскольку кнопка "Назад" зависит от правила стиля `#backButton` (определенного в `stylesheet.css`), это правило становится блокированным, если идентификатор JSF предшествует идентификатору кнопки. Этого можно избежать, если для `prependId` установить значение `false`. |
| |
| |
| [start=10] |
| . Повторно запустите проект (нажмите кнопку 'Запустить проект' ( image:images/run-project-btn.png[] ) или нажмите F6; fn-F6 в Mac). Введите число на странице приветствия, затем нажмите кнопку "Отправить". Теперь на странице ответа отображается ответное сообщение без тегов `<p>`, и кнопка "Назад" размещена правильно. |
| |
| image::images/response3.png[title="Просмотрит текущее состояния проекта в браузере"] |
| |
| [start=11] |
| . Нажмите кнопку "Назад". Поскольку текущее значение свойства `userNumber` для `UserNumberBean` привязано к компоненту `inputText` JSF, ранее введенное число теперь отображается в текстовом поле. |
| |
| [start=12] |
| . Проверьте протокол сервера в окне вывода среды IDE (CTRL+4; &#8984+4 на компьютере Mac) для определения правильного загаданного числа. |
| |
| Если по каким-то причинам просмотреть протокол сервера невозможно, откройте его посредством переключения на окно "Службы" (CTRL+5; &#8984+5 на компьютере Mac) и развертывания узла "Серверы". Затем щелкните правой кнопкой мыши сервер GlassFish, на котором развернут проект и выберите 'Просмотреть журнал сервера'. Если номер не отображается в журнале сервера, попробуйте повторно выполнить сборку приложения, щелкнув правой кнопкой мыши узел проекта и выбрав 'Очистка и сборка'. |
| |
| |
| [start=13] |
| . Введите правильное число и нажмите кнопку "Отправить". В приложении происходит сравнение введенного числа с текущим сохраненным числом и выводится соответствующее сообщение. |
| |
| image::images/yay.png[title="При вводе соответствующего числа отображается правильный отклик"] |
| |
| [start=14] |
| . Нажмите еще раз кнопку "Назад". Обратите внимание на то, что ранее введенное число более не отображается в текстовом поле. Следует помнить о том, что метод `getResponse()` для `UserNumberBean` <<getResponse,определяет текущий пользовательский сеанс как недействительный>> при угадывании правильного числа. |
| |
| |
| |
| [[template]] |
| == Применение шаблона Facelets |
| |
| Facelets сегодня является стандартной технологией отображения для JSF 2.x. Facelets - это облегченная платформа шаблонов, которая поддерживает все компоненты JSF пользовательского интерфейса и используется для построения и визуализации дерева компонентов JSF для просмотра приложений. Кроме того, эта технология обеспечивает поддержку разработки при возникновении ошибок языка выражений за счет возможности проверять трассировку стека, дерево компонентов и контекстные переменные. |
| |
| Хотя, возможно, вы об этом не задумывались, файлы `index.xhtml` и `response.xhtml`, с которыми вы работаете в этом руководстве, являются страницами Facelets. Страницы Facelets имеют расширение `.xhtml` и, поскольку вы работаете в проекте JSF 2.x (библиотеки JSF 2.x включают в себя файлы JAR Facelets), эти представления способны надлежащим образом визуализировать дерево компонентов JSF. |
| |
| Целью этого раздела является знакомство с созданием шаблона Facelets. Для проектов с несколькими представлениями зачастую полезно применять файл шаблона, определяющего структуру и внешний вид для нескольких представлений. При обслуживании запросов приложение вставляет динамически подготовленное содержимое во временный файл и отправляет результат обратно клиенту. Хотя данный проект имеет только два представления (страницу приветствия и страницу ответа), можно легко отметить, что большая часть содержимого в них дублируется. Это дублированное содержимое можно перенести в шаблон Facelets и создать файлы клиента шаблона для обработки содержимого, которое является специфичным для страницы приветствия и страницы ответа. |
| |
| В среде IDE существует link:jsf20-support.html#faceletsTemplate[+мастер создания шаблона Facelets+] для создания шаблонов Facelets и мастер создания клиента шаблона Facelets для создания файлов, зависящих от шаблона. В этом разделе описано использование этих мастеров. |
| |
| *Примечание.* IDE также предоставляет мастер страниц JSF, что позволяет создавать индивидуальные страницы Facelets для проекта. Подробнее см. в разделе link:jsf20-support.html#jsfPage[+Поддержка JSF 2.x в IDE NetBeans+]. |
| |
| * <<templateFile,Создание файла шаблона Facelets>> |
| * <<templateClient,Создание файлов клиента шаблона>> |
| |
| |
| [[templateFile]] |
| === Создание файла шаблона Facelets |
| |
| 1. Создайте файл шаблона Facelets. Нажмите сочетание клавиш CTRL+N (&#8984+N на компьютере Mac) для открытия мастера создания файлов. Выберите категорию "JavaServer Faces", затем "Шаблон Facelets". Нажмите кнопку "Далее". |
| 2. В поле "Имя файла" введите `template`. |
| 3. Выберите один из восьми стилей размещения и нажмите кнопку "Готово". (Вы будете использовать существующую таблицу стилей, так что не имеет значения, какой стиль вы выберете.) |
| |
| image::images/layout-style.png[title="Мастер шаблонов Facelets позволяет сделать выбор из распространенных стилей компоновки"] |
| |
| Мастером будут созданы файл `template.xhtml` и сопутствующие таблицы стилей на основе выбора, которые будут помещены в папку `resources` > `css` в корневом веб-узле проекта. |
| |
| После завершения выполнения мастера в редакторе открывается файл шаблона. Для просмотра шаблона в браузере, щелкните правой кнопкой мыши в редакторе и выберите 'Просмотр'. |
| |
| |
| [start=4] |
| . Проверьте разметку файла шаблона. Обратите внимание на следующие моменты. |
| * Библиотека тегов `facelets` объявлена в теге `<html>` страницы. Библиотека тегов имеет префикс `ui`. |
| |
| [source,java] |
| ---- |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" |
| *xmlns:ui="http://xmlns.jcp.org/jsf/facelets"* |
| xmlns:h="http://xmlns.jcp.org/jsf/html"> |
| ---- |
| * На странице Facelets используются теги `<h:head>` и `<h:body>` вместо тегов HTML `<head>` и `<body>`. При использовании этих тегов у Facelets появляется возможность создания дерева компонентов, которое включает в себя всю страницу. |
| * Страница ссылается на таблицы стилей, которые также создаются при завершении выполнения мастера. |
| |
| [source,xml] |
| ---- |
| |
| <h:head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| *<link href="./resources/css/default.css" rel="stylesheet" type="text/css" />* |
| *<link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />* |
| <title>Facelets Template</title> |
| </h:head> |
| ---- |
| * Теги `<ui:insert>` используются в теле страницы для каждого раздела, связанного с выбранным стилем размещения. Каждый тег `<ui:insert>` имеет атрибут `name`, определяющий раздел. Например: |
| |
| [source,html] |
| ---- |
| |
| <div id="top"> |
| *<ui:insert name="top">Top</ui:insert>* |
| </div> |
| ---- |
| |
| [start=5] |
| . Повторно проверьте страницу <<staticPage,приветствия>> и страницу <<responsePage,ответа>>. Содержимым, которое изменяется на этих страницах, является только заголовок и текст в сером квадрате. Следовательно, шаблон может включать в себя все остальное содержимое. |
| |
| [start=6] |
| . Замените все содержимое файла шаблона содержимым, приведенным ниже. |
| |
| [source,html] |
| ---- |
| |
| <?xml version='1.0' encoding='UTF-8' ?> |
| <!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" |
| xmlns:ui="http://xmlns.jcp.org/jsf/facelets" |
| xmlns:h="http://xmlns.jcp.org/jsf/html"> |
| |
| <h:head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| <link href="css/stylesheet.css" rel="stylesheet" type="text/css" /> |
| |
| <title><ui:insert name="title">Facelets Template</ui:insert></title> |
| </h:head> |
| |
| <h:body> |
| |
| <div id="left"> |
| <ui:insert name="box">Box Content Here</ui:insert> |
| </div> |
| |
| </h:body> |
| |
| </html> |
| ---- |
| Приведенный выше код реализует следующие изменения. |
| * Файл `stylesheet.css` проекта заменяет ссылки на таблицу стилей шаблона, созданные в мастере. |
| * Все теги `<ui:insert>` (вместе с тегами `<div>`) удаляются за исключением одного с именем `box`. |
| * В теги `<ui:insert>` вставляется заголовок страницы с именем `title`. |
| |
| [start=7] |
| . Скопируйте в шаблон соответствующий код из файла `index.xhtml` или файла `response.xhtml`. Добавьте содержимое, отображаемое ниже *полужирным шрифтом*, в теги `<h:body>` файла шаблона. |
| |
| [source,html] |
| ---- |
| |
| <h:body> |
| *<div id="mainContainer">* |
| <div id="left" *class="subContainer greyBox"*> |
| <ui:insert name="box">Box Content Here</ui:insert> |
| </div> |
| *<div id="right" class="subContainer"> |
| <img src="duke.png" alt="Duke waving" /> |
| </div> |
| </div>* |
| </h:body> |
| ---- |
| |
| [start=8] |
| . Выполните проект. При открытии страницы приветствия в браузере измените URL-адрес на следующий: |
| |
| [source,java] |
| ---- |
| |
| http://localhost:8080/jsfDemo/faces/template.xhtml |
| ---- |
| Файл шаблона отображается следующим образом: |
| |
| image::images/facelets-template.png[title="Просмотрите шаблон Facelets в браузере"] |
| |
| Теперь проект включает в себя файл шаблона, предоставляющий внешний вид и структуру всех представлений. Теперь можно создавать файлы клиента для вызова шаблона. |
| |
| |
| [[templateClient]] |
| === Создание файлов клиента шаблона |
| |
| Создайте файлы клиента шаблона для страниц приветствия и ответа. Укажите имя файла клиента шаблона для страницы приветствия `greeting.xhtml`. Для страницы ответа – файл `response.xhtml`. |
| |
| |
| ==== greeting.xhtml |
| |
| 1. Нажмите сочетание клавиш CTRL+N (⌘-N на компьютере Mac) для открытия мастера создания файлов. Выберите категорию "JavaServer Faces", затем "Клиент шаблона Facelets". Нажмите кнопку "Далее". |
| 2. В поле "Имя файла" введите `greeting`. |
| 3. Нажмите кнопку "Обзор" рядом с полем "Шаблон", затем в открывшемся диалоговом окне перейдите к файлу `template.xhtml`, созданному в предыдущем разделе. |
| |
| image::images/template-client.png[title="Мастер создания клиентов шаблона Facelets"] |
| |
| [start=4] |
| . Нажмите кнопку "Завершить". Будет создан новый файл клиента шаблона `greeting.xhtml`, который откроется в редакторе. |
| |
| [start=5] |
| . Проверьте разметку. Обратите внимание на содержимое, выделенное *полужирным шрифтом*. |
| |
| [source,xml] |
| ---- |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" |
| xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> |
| |
| <body> |
| |
| <ui:composition *template="./template.xhtml"*> |
| |
| <ui:define *name="title"*> |
| title |
| </ui:define> |
| |
| <ui:define *name="box"*> |
| box |
| </ui:define> |
| |
| </ui:composition> |
| |
| </body> |
| </html> |
| ---- |
| Файл клиента шаблона ссылается на шаблон с помощью атрибута `template` тега `<ui:composition>`. Поскольку шаблон содержит теги `<ui:insert>` для `title` и `box`, клиент шаблона содержит теги `<ui:define>` для этих двух имен. Содержимое, указываемое в тегах `<ui:define>`, - это содержимое, вставляемое в шаблон в тегах `<ui:insert>` соответствующего имени. |
| |
| [start=6] |
| . Укажите `greeting` в качестве заголовка файла. Внесите следующее изменение, выделенное *полужирным шрифтом*. |
| |
| [source,xml] |
| ---- |
| |
| <ui:define name="title"> |
| *Greeting* |
| </ui:define> |
| ---- |
| |
| [start=7] |
| . Перейдите к файлу `index.xhtml` (нажмите CTRL+TAB) и скопируйте содержимое, которое обычно появляется в сером квадрате, выведенном на визуализируемой странице. Затем обратно переключитесь на файл `greeting.xhtml` и вставьте его в файл клиента шаблона. (Изменения *выделены полужирным шрифтом*.) |
| |
| [source,xml] |
| ---- |
| |
| <ui:define name="box"> |
| *<h4>Hi, my name is Duke!</h4> |
| |
| <h5>I'm thinking of a number |
| |
| <br/> |
| between |
| <span class="highlight">0</span> and |
| <span class="highlight">10</span>.</h5> |
| |
| <h5>Can you guess it?</h5> |
| |
| <h:form> |
| <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" /> |
| <h:commandButton id="submit" value="submit" action="response" /> |
| </h:form>* |
| </ui:define> |
| ---- |
| |
| [start=8] |
| . Объявите библиотеку тегов HTML JSF для файла. Установите курсор на один из тегов, помеченных флагом ошибки (любой тег с префиксом "`h`"), и нажмите сочетание клавиш CTRL+ПРОБЕЛ. Затем выберите тег из списка предложений автозавершения кодов. Пространство имен библиотеки тегов добавляется к тегу `<html>` файла (выделено ниже *полужирным шрифтом*), и указания на ошибки исчезают. |
| |
| [source,java] |
| ---- |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" |
| xmlns:ui="http://xmlns.jcp.org/jsf/facelets" |
| *xmlns:h="http://xmlns.jcp.org/jsf/html"*> |
| ---- |
| |
| При установке курсора после "`m`" в `<h:form>` и нажатии сочетания клавиш CTRL+ПРОБЕЛ к файлу автоматически добавляется пространство имен. Если при нажатии сочетания клавиш CTRL+ПРОБЕЛ доступен только один логический параметр, он немедленно применяется к файлу. Библиотека тегов JSF автоматически объявляется при вызове автозавершения кода в тегах. |
| |
| |
| ==== response.xhtml |
| |
| Поскольку проект уже содержит файл с именем `response.xhtml` и известно, как теперь должен выглядеть файл клиента шаблона, измените существующий файл `response.xhtml`, чтобы получить соответствующий файл клиента шаблона. (В целях данного руководства просто скопируйте и вставьте предоставленный код.) |
| |
| 1. Откройте файл `response.xhtml` в редакторе. (Если он уже открыт, нажмите CTRL+TAB и выберите его). Замените содержимое всего файла нижеприведенным кодом. |
| |
| [source,xml] |
| ---- |
| |
| <?xml version='1.0' encoding='UTF-8' ?> |
| <!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" |
| xmlns:ui="http://xmlns.jcp.org/jsf/facelets" |
| xmlns:h="http://xmlns.jcp.org/jsf/html"> |
| |
| <body> |
| |
| <ui:composition template="./template.xhtml"> |
| |
| <ui:define name="title"> |
| Response |
| </ui:define> |
| |
| <ui:define name="box"> |
| <h4><h:outputText escape="false" value="#{UserNumberBean.response}"/></h4> |
| |
| <h:form prependId="false"> |
| |
| <h:commandButton id="backButton" value="Back" action="greeting" /> |
| |
| </h:form> |
| </ui:define> |
| |
| </ui:composition> |
| |
| </body> |
| </html> |
| ---- |
| Обратите внимание на то, что файл идентичен файлу `greeting.xhtml`, за исключением содержимого, указанного в тегах `<ui:define>` для `title` и `box`. |
| |
| [start=2] |
| . В дескрипторе развертывания `web.xml` проекта измените запись файла приветствия таким образом, чтобы при запуске приложения открывалась страница, представленная файлом `greeting.xhtml`. |
| |
| В окне 'Проекты' дважды щелкните 'Файлы конфигурации' > `web.xml`, чтобы открыть его в редакторе. На вкладке "Страницы" измените поле "Файлы приветствия" на `faces/greeting.xhtml`. |
| |
| image::images/welcome-files.png[title="Измените запись 'Файлы приветствия' в дескрипторе развертывания"] |
| |
| [start=3] |
| . Выполните проект и посмотрите, как он выглядит в браузере. Нажмите F6 (fn-F6 в Mac) или нажмите кнопку 'Запустить проект'( image:images/run-project-btn.png[] ) на главной панели инструментов. Проект будет развернут на сервере GlassFish и открыт в браузере. |
| |
| При использовании шаблона Facelets и файлов клиента шаблона поведение приложения не меняется. Выделив повторяющийся код на страницах приветствия и ответа приложения, можно уменьшить размер приложения и устранить возможность написания повторяющегося кода, если впоследствии будут добавляться другие страницы. Это позволяет сделать разработку более эффективной и упростить управление при работе с большими проектами. |
| |
| link:/about/contact_form.html?to=3&subject=Feedback:%20Introduction%20to%20JSF%202.0[+Отправить отзыв по этому учебному курсу+] |
| |
| |
| |
| [[seealso]] |
| == Дополнительные сведения |
| |
| Подробнее о JSF 2.x см. в следующих ресурсах. |
| |
| |
| === Статьи и учебные курсы по NetBeans |
| |
| * link:jsf20-support.html[+Поддержка JSF 2.x в IDE NetBeans+] |
| * link:jsf20-crud.html[+Создание приложения JavaServer Faces 2.x CRUD на основе базы данных+] |
| * link:../../samples/scrum-toys.html[+Scrum Toys – полный пример приложения JSF 2.0+] |
| * link:../javaee/javaee-gettingstarted.html[+Начало работы с приложениями Java EE+] |
| * link:../../trails/java-ee.html[+Учебная карта по Java EE и Java Web+] |
| |
| |
| === Внешние ресурсы |
| |
| * link:http://www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html[+Технология JavaServer Faces+] (официальная домашняя страница) |
| * link:http://jcp.org/aboutJava/communityprocess/final/jsr314/index.html[+Спецификация JSR 314 для JavaServer Faces 2.0+] |
| * link:http://docs.oracle.com/javaee/7/tutorial/doc/jsf-develop.htm[+Учебный курс по Java EE 7. Глава 12. Разработка по технологии JavaServer Faces+] |
| * link:http://javaserverfaces.dev.java.net/[+GlassFish Project Mojarra+] (официальный пример реализации JSF 2.х) |
| * link:http://forums.oracle.com/forums/forum.jspa?forumID=982[+Интернет-форум OTN: JavaServer Faces+] |
| * link:http://www.jsfcentral.com/[+JSF Central+] |
| |
| |
| === Блоги |
| |
| * link:http://www.java.net/blogs/edburns/[+Эд Бернс (Ed Burns)+] |
| * link:http://www.java.net/blogs/driscoll/[+Джим Дрисколл (Jim Driscoll)+] |