Введение в Java Server Faces
В наше «смутное» время развитие Web-технологий идет семимильными шагами, еще недавно web-программистам приходилось жутко напрягаться в процессе написания интернет-приложений, используя технологию CGI, формируя html-поток буквально вручную. Прошло некоторое время, были созданы такие, очень полезные, вещи – как, JSP, ASP, PHP, которые позволили разделить дизайн web-страниц и бизнесс-логику, чем немало порадовали, в первую очередь, программистов, ну и конечно web-дизайнеров. Однако не все так радужно, как кажется. Тот, кто заглядывал в исходники, к примеру, PHP приложений меня поймут. Мешанина программного кода и html разметки никого не оставят равнодушными.Корпорация Microsoft сделала большой шаг вперед, создав
технологию ASP.NET. Данная технология позволила полностью разделить
view и логику web-приложений. С помощью этой технологии стало
возможным создание качественных приложений в кратчайшие сроки, с
применением объектно-ориентированной парадигмы, о которой в наше
время не знает только ленивый. Поклонников Microsoft, которых сейчас
распирает гордость, прошу удалиться. Если же вы менее консервативны
– оставайтесь, буду очень рад :) Речь пойдет об альтернативной
технологии под названием Java Server Faces.
Java Server
Faces (JSF) – компонентная, событийно-ориентированная технология
создания web-приложений от авторов Java. Технология еще очень
молода, и находиться на этапе становления и совершенствования. Те не
менее, я думаю, JSF станет одним из основных «китов»
web-программирования в ближайшее время. В данном случае, в отличие
от .NET, не вызывает сомнения реальная кроссплатформенность
создаваемых приложений.
Итак, начнем. Мы напишем простенькую
гостевую книгу с применением JSF. Для создания этого приложения нам
понадобится следующее ПО:
- Операционная система (linux or windows), на ваш вкус. :)
- Java 2 SDK, Standard Edition
- Набор JSF-библиотек
- Сервер приложений tomcat версии 4 или 5
- Интегрированная среда разработки (IDE)
По поводу IDE,
советую NetBeans 3.6 (скоро должен выйти релиз 4.0). Почему?
Во первых - NetBeans совершенно бесплатен, во вторых - в комплект
IDE входит сервер приложений tomcat, в третьих – это действительно
отличная среда разработки. Для любителей экстрима вполне подойдут
emacs, vi, или блокнот :)
Устанавливаем все
вышеперечисленное, вернее установки требует только сама java (не
считая операционки), все остальное просто распаковывается из архивов
и копируется в любое место диска по вашему вкусу. Не забудьте
прописать переменную окружения JAVA_HOME, она должна
указывать на корневую директорию, куда былау становлена java,
например c:\j2sdk1.4.2_05.
Структура каталогов нашего
приложения такова:
Каталог GuestBook является корнем приложения, в нем располагаются следующие JSP-страницы:
- guest.jsp – непосредственно гостевуха, вернее её интерфейсная часть;
- success.jsp – страница подтверждающая, что сообщение успешно внесено;
- failure.jsp – страница с сообщением об ошибке, если таковая возникнет;
- index.jsp – так, для порядку.
Для создания типичного JSF-приложения необходимо последовательно решить несколько задач:
- Создать JSP-страницу, содержащую html разметку, пользовательские теги, теги серверных элементов управления.
- Определить правила навигации между страницами в конфигурационном файле. В нашем случае это файл /WEB-INF/navigation.xml.
- Разработать backing bean,у нас это файл /WEB-INF/classes/backbeans/GuestBean.java, но об этом немного позже.
- Описать созданный backing bean в конфигурационном файле приложения(/WEB-INF/managed-beans.xml)
Прежде чем использовать faces-теги на JSP-странице, необходимо подключить библиотеки тегов:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> и <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> |
Страница Java Server Faces представлена в виде дерева компонентов, корневым компонентом которого является UIViewRoot. На нашей странице его представляет тег
<f:view> <h:form> ... другие faces-теги, перемешанные со всем остальным... </h:form> </f:view> |
Тег
Текстовое поле представляет тег
<h:inputText id="txtMail" value="#{GuestBean.mail}" style="width:100%" /> |
Программный вывод текста на страницу осуществляется с помощью тега
<h:outputText id="txtMailError" value="#{GuestBean.mailError}" /> |
С его помощью, в данном случае, выводятся сообщение об ошибке, т.е. красная звездочка рядом с текстовым полем, обязательным для заполнения. Один из важнейших элементов управления – кнопка, реализуется с помощью тега
<h:commandButton id="btnSend" action="#{GuestBean.onClick}" value="Сохранить" /> |
Благодаря атрибуту action, мы связываем событие нажатия кнопки с обработчиком, находящимся в backing bean.
Содержимое гостевой книги отображается с помощью таблицы, связываемой с источником данных. Тег
Теперь о backing bean.
Реализованный в классе GuestBook он наследует абстрактный класс FacesBean. В классе FacesBean реализовано много полезных методов, в том числе, связанных с жизненным циклом jsf-страницы, поэтому делай как я :) При необходимости можно эти методы переопределить и использовать в своих корыстных интересах. Не забудьте подключить к приложению библиотеку jsfcl.jar - именно в ней и определен класс FacesBean.
В соответствии со спецификацией Java Beans свойства определяются как пара get и set методов.
private String mail; public String getMail() {return mail;} public void setMail(String value) {mail = value;} |
Вышеприведенный код определяет свойство с именем mail, именно mail (с маленькой буквы). Почему? Потому что - надо, серьезные дяди из Sun Microsystems так решили, придумывая Java Beans. Свойство mail связывается с текстовым полем для ввода e-mail и хранит его значение. Разумеется, при необходимости, методы getMail и setMail можно использовать более интеллектуально, нежели просто для присваивания значения закрытой переменной. Свойство «только для чтения» создается реализацией единственного get-метода
В конструкторе класса мы загружаем настройки соединения с базой данных и инициализируем переменную rowset, заполняя ее набором данных из таблицы tblGuest.
public GuestBean() { // загружаем параметры соединения с БД DRIVER_CLASS = this.getExternalContext().getInitParameter ("driver_class"); DB_HOST = this.getExternalContext().getInitParameter("db_host"); DB_USER = this.getExternalContext().getInitParameter("db_user"); DB_PASSWORD = this.getExternalContext().getInitParameter("db_password"); // заполняем набор данных rowset = getDataSource(); } |
Содержимое набора данных rowset будет отображено на web-странице с помощью faces-тега
<h:dataTable id="grid" value="#{GuestBean.rowSet}" var="set"> ... </h:dataTable> |
Параметры соединения с БД описаны в файле web.xml
<context-param> <param-name>driver_class</param-name> <param-value>net.sourceforge.jtds.jdbc.Driver</param-value> </context-param> <context-param> <param-name>db_host</param-name> <param-value>jdbc:jtds:sqlserver://localhost:1433/guest </param-value> </context-param> <context-param> <param-name>db_user</param-name> <param-value>xxx</param-value> </context-param> <context-param> <param-name>db_password</param-name> <param-value>xxx</param-value> </context-param> |
Наверняка вам понадобится тут кое-что подправить. Я использовал MS SQL Server, вы можете использовать альтернативную СУБД. Не забудьте поместить в директорию /WEB-INF/lib соответствующий jdbc-драйвер и изменить параметры соединения в web.xml.
Что собой представляет обработчик события?
// Обработчик клика кнопки public String onClick() { if(!validate()) return ""; boolean result = saveToDatabase(); // возвращаем значения для navigation rules if(result) return "success"; else return "failure"; } |
При нажатии на кнопку «Сохранить» вызывается функция onClick(), происходит проверка введенных значений с помощью функции validate(), затем инфа сохраняется в базу. Функция onClick() может возвращать три различных значения, это необходимо для реализации навигации между страницами. Правила навигации описаны в файле navigation.xml.
<faces-config> <navigation-rule> <from-view-id>/guest.jsp</from-view-id> <navigation-case> <from-action>#{GuestBean.onClick}</from-action> <from-outcome>success</from-outcome> <to-view-id>/success.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{GuestBean.onClick}</from-action> <from-outcome>failure</from-outcome> <to-view-id>/failure.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config> |
Если сообщение успешно записано в базу - onClick() вернет строку "success", все хорошо, вперед к странице success.jsp, где мы увидим подтверждение сего замечательного события. Если произошла ошибка при работе с СУБД, то onClick() вернет строку "failure", все плохо, мы увидим страницу с сообщением об ошибке. В этом случае, скорее всего, проблемы гнездятся в параметрах соединения с СУБД. Если введенная (или не введенная) пользователем инфа, не прошла валидацию - onClick() вернет пустую строку. Поскольку такой вариант не предусмотрен в правилах навигации, пользователь получит назад исходную страницу.
Созданный backing bean необходимо описать в файле конфигурации, присвоить ему псевдоним и область видимости. Заглянем в файл managed-beans.xml.
<faces-config> <managed-bean> <managed-bean-name>GuestBean</managed-bean-name> <managed-bean-class>backbeans.GuestBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-config> |
Сия запись означает, что классу GuestBean из пакета backbeans назначается псевдоним GuestBean и область видимости request. Псевдоним необходим для того, чтобы с его помощью обращаться к свойствам и событиям класса из JSP-страниц. У директивы
- request – класс создается при каждом запросе;
- session – класс создается при первом запросе и «живет» до конца сессии;
- application – класс создается при старте приложения и «живет» пока существует приложение.
<context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value>/WEB-INF/navigation.xml,/WEB-INF/managed-beans.xml </param-value> </context-param> |
Этим мы ставим в известность JFS-framework, о существовании конфигурационных файлов navigation.xml и managed-beans.xml.
<servlet> <servlet-name>Faces</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> |
Объявляем FacesServlet и задаем для него псевдоним.
<servlet-mapping> <servlet-name>Faces</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> |
Говорим, что все страницы с URL /faces/* должны быть обработаны jsf-framework.
<welcome-file-list> <welcome-file>faces/guest.jsp</welcome-file> </welcome-file-list> |
Задаем стартовую страницу приложения.
Для развертывания нашего приложения, распакуйте архив с сервером Tomcat. Запустите сервер, перейдя в подкаталог bin и, запустив скрипт startup.bat в windows, или startup.sh в linux. Наберите в браузере http://localhost:8080/. Если вы увидели главную страницу с веселым котенком, то половина дела сделано – сервер работает. Иначе проверьте переменную окружения JAVA_HOME - это основная причина неудачи. Само собой, я не рассматриваю такие экстремальные варианты, как отсутствие виртуальной машины java на вашем компьютере :)
Запакуйте наше приложение любым zip архиватором и назначьте файлу расширение *.war. Скопируйте архив в подкаталог webapps сервера приложений. Наберите в браузере http://localhost:8080/GuestBook - вот и все. Само собой, с первого раза работать не будет – смотрите параметры соединения с базой данных в файле web.xml. И еще, маленькая деталь – создайте предварительно базу данных, к примеру, с именем guest, в базе таблицу tblGuest.
Структура таблицы:
Удачи и счастья!!!
Исходный код приложения, со всеми необходимыми библиотеками GuestBook.rar
Архив web-приложения GuestBook.war
Февраль 2006 г.