В этот раз у нас появится Java-код. Будем писать форму и логику обработки введенных данных.
Пост
НЕ для тех, кто знает что такое JSF 2 и/или JSF 1.2, а faces-config.xml — не просто файл в проекте. Смотрите, я предупреждал…
CDI
С версии JSF 2.3.0 стандартная аннотация
@ManagedBean
признана устаревшей. Т.е. чтобы обратиться к своему Java-коду из формы нам потребуется добавить в проект CDI (Context and Dependency Injection) —
Weld.
В файл
pom.xml
добавляем:
...
org.jboss.weld.servlet
weld-servlet
2.4.3.Final
Создадим файл
/src/main/webapp/WEB-INF/beans.xml
:
Вредный советВ комментариях к
прошлому посту заметили:
Там прям особая специфика в регистрации listener'а?
ОК! В файл
/src/main/webapp/WEB-INF/web.xml
добавляем:
org.jboss.weld.environment.servlet.Listener
...
Запускаем:
mvn jetty:run
Читаем
traceback почему не работает.
Создадим файл
/src/main/webapp/WEB-INF/jetty-env.xml
:
-org.eclipse.jetty.server.handler.ContextHandler
-org.eclipse.jetty.servlet.FilterHolder
-org.eclipse.jetty.servlet.ServletContextHandler
-org.eclipse.jetty.servlet.ServletHolder
BeanManager
javax.enterprise.inject.spi.BeanManager
org.jboss.weld.resources.ManagerObjectFactory
В файл
/src/main/webapp/WEB-INF/web.xml
добавляем:
BeanManager
javax.enterprise.inject.spi.BeanManager
...
Теперь вместо
@ManagedBean
будет работать
@Named
.
Учитывая что CDI штука хорошая, а с версии JSF 2.3.0 — критичная, стоит понимать что CDI в JSF используется по своему прямому назначению и к JSF непосредственно отношения не имеет.
Больше к CDI мы возвращаться не будем!
Классы FormData и FormCtrl
Теперь давайте напишем немного кода. Нам потребуется 2 класса — в 1-ом мы будем передавать данные, во 2-ом будет функция обработки этих данных.
ОтступлениеС точки зрения реализации — не обязательно выделять логику формы в 2 отдельных класса, но это «правильно» как с точки зрения тестирования, так и сточки зрения архитектуры.
Класс-данных
/src/main/java/ru/habr/FormData.java
:
package ru.habr;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
@Named
@RequestScoped
public class FormData {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Класс-обработчик
/src/main/java/ru/habr/FormCtrl.java
:
package ru.habr;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@RequestScoped
public class FormCtrl {
@Inject
FormData formData;
public String doAction() {
// Очень полезные действия с данными...
System.out.println(formData.getUsername());
System.out.println(formData.getPassword());
return null;
}
}
Если с
FormData
все понятно, то на
FormCtrl
стоит взглянуть пристальней:
- Благодаря
@Inject
, данные формы будут доступны в классе-обработчике в поле formData
.
- Рекомендую придерживаться тезиса «метод-обработчик должен возвращать строку» хоть это и не обязательно. Строка в дальнейшем используется в навигации, но об этом позже.
Форма
Тут все просто!
В файл
/src/main/webapp/index.xhtml
добавляем:
...
Запускаем:
mvn jetty:run
Проверяем:
http://127.0.0.1:8080/
AJAX
На дворе 2017 год, а формы все еще без AJAX?!
В файл
/src/main/webapp/index.xhtml
внесем пару правок:
...
...
Что изменилось:
- Добавилось определение библиотеки тегов
xmlns:f="http://xmlns.jcp.org/jsf/core"
. Без этого можно реализовать AJAX, но обрабатывать придется ручками, что долго и неблагодарно.
- Внутри
h:commandButton
появился
. В execute
— указываем что необходимо отправить на сервер (всю форму/все поля формы), в render
— что необходимо обновить с сервера после выполнения AJAX.
Про
f:ajax
можно писать отдельный. Сейчас достаточно знать только что с его помощью можно отправить/обновить не только текущую форму на странице, а любой элемент страницы.
Послесловие
Проект все еще очень скромен в своих возможностях, но я
буду продолжать!
https://habrahabr.ru/post/330146/