1. Введение
Это вторая часть интеграции Thymeleaf с руководством Spring. Вы можете прочитать первую часть здесь , где вы узнаете, как настроить этот проект.
Как объяснялось в начале первой части этого руководства, веб-приложение будет отправлять два типа запросов:
- Вставить нового гостя: отправляет синхронный запрос на сервер для добавления нового гостя. Это продемонстрирует, как Thymeleaf интегрируется с бобами поддержки формы Spring.
- Список гостей: отправляет запрос AJAX, который обновит регион ( фрагмент ) страницы, чтобы показать список гостей, возвращенный с сервера.
Посмотрим, как мы этого добьемся.
2. Обработка форм
В этом разделе мы увидим, как форма отправляется с помощью Thymeleaf. Нам понадобятся три атрибута:
- го: действие
- го: объект
- го: поле
Первые два определены в элементе формы:
1
|
< form id = "guestForm" th:action = "@{/spring/guests/insert}" th:object = "${guest}" method = "post" > |
Атрибут th: action переписывает URL-адрес действия, добавляя к нему префикс контекста приложения.
Атрибут th: object в элементе формы — это выбор объекта. На него можно ссылаться в форме. Здесь мы привязываем компонент поддержки формы к атрибуту модели, который мы определили в контроллере перед рендерингом представления:
1
2
3
4
|
@ModelAttribute ( "guest" ) public Guest prepareGuestModel() { return new Guest(); } |
Как мы видим, th: object ссылается на компонент поддержки Гостевой формы, а th: field ссылается на его свойства. Посмотрите на форму тела:
01
02
03
04
05
06
07
08
09
10
11
|
< span class = "formSpan" > < input id = "guestId" type = "text" th:field = "*{id}" required = "required" /> < br /> < label for = "guestId" th:text = "#{insert.id}" >id:</ label > </ span > < span class = "formSpan" style = "margin-bottom:20px" > < input id = "guestName" type = "text" th:field = "*{name}" required = "required" /> < br /> < label for = "guestName" th:text = "#{insert.name}" >name:</ label > </ span > |
Что th: field будет делать, так это присваивать значение своего входного элемента свойству bean-компонента. Таким образом, когда пользователь отправляет форму, все эти поля th: устанавливают свойства компонента поддержки формы.
На контроллере мы получим гостевой экземпляр:
1
2
3
4
5
6
|
@RequestMapping (value = "/guests/insert" , method = RequestMethod.POST) public String insertGuest(Guest newGuest, Model model) { hotelService.insertNewGuest(newGuest); return showHome(model); } |
Теперь гость может быть вставлен в базу данных.
3. Отправка запросов AJAX
Пытаясь найти простой пример отправки AJAX-запроса с Thymeleaf, я нашел примеры с Spring Webflow ( рендеринг фрагментов ). Я также читал, что другие говорят, что вам нужен Tiles для этого.
Я не хотел использовать эти фреймворки, поэтому в этом разделе я использую jQuery для отправки AJAX-запроса на сервер, ожидания ответа и частичного обновления представления (рендеринг фрагмента).
Форма
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
< form > < span class = "subtitle" >Guest list form</ span > < div class = "listBlock" > < div class = "search-block" > < input type = "text" id = "searchSurname" name = "searchSurname" /> < br /> < label for = "searchSurname" th:text = "#{search.label}" >Search label:</ label > < button id = "searchButton" name = "searchButton" onclick = "retrieveGuests()" type = "button" th:text = "#{search.button}" >Search button</ button > </ div > <!-- Results block --> < div id = "resultsBlock" > </ div > </ div > </ form > |
Эта форма содержит текст ввода со строкой поиска (searchSurname), которая будет отправлена на сервер. Также есть регион (resultsBlock div), который будет обновляться в соответствии с ответом, полученным с сервера.
Когда пользователь нажимает кнопку, вызывается функция retrieveGhest ().
1
2
3
4
5
6
7
8
9
|
function retrieveGuests() { var url = '/th-spring-integration/spring/guests' ; if ($( '#searchSurname' ).val() != '' ) { url = url + '/' + $( '#searchSurname' ).val(); } $( "#resultsBlock" ).load(url); } |
Функция загрузки jQuery делает запрос к серверу по указанному URL-адресу и помещает возвращенный HTML-код в указанный элемент (resultsBlock div).
Если пользователь вводит строку поиска, он будет искать всех гостей с указанной фамилией. В противном случае он вернет полный список гостей. Эти два запроса достигнут следующих отображений запросов контроллера:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@RequestMapping (value = "/guests/{surname}" , method = RequestMethod.GET) public String showGuestList(Model model, @PathVariable ( "surname" ) String surname) { model.addAttribute( "guests" , hotelService.getGuestsList(surname)); return "results :: resultsList" ; } @RequestMapping (value = "/guests" , method = RequestMethod.GET) public String showGuestList(Model model) { model.addAttribute( "guests" , hotelService.getGuestsList()); return "results :: resultsList" ; } |
Поскольку Spring интегрирован с Thymeleaf, он теперь сможет возвращать фрагменты HTML. В приведенном выше примере возвращаемая строка «results :: resultsList» ссылается на фрагмент с именем resultsList, который находится на странице результатов. Давайте посмотрим на эту страницу результатов:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<! DOCTYPE html> < head > </ head > < body > < div th:fragment = "resultsList" th:unless = "${#lists.isEmpty(guests)}" class = "results-block" > < table > < thead > < tr > < th th:text = "#{results.guest.id}" >Id</ th > < th th:text = "#{results.guest.surname}" >Surname</ th > < th th:text = "#{results.guest.name}" >Name</ th > < th th:text = "#{results.guest.country}" >Country</ th > </ tr > </ thead > < tbody > < tr th:each = "guest : ${guests}" > < td th:text = "${guest.id}" >id</ td > < td th:text = "${guest.surname}" >surname</ td > < td th:text = "${guest.name}" >name</ td > < td th:text = "${guest.country}" >country</ td > </ tr > </ tbody > </ table > </ div > </ body > </ html > |
Фрагмент, представляющий собой таблицу с зарегистрированными гостями, будет вставлен в блок результатов:
4. Вывод
После интеграции обеих платформ мы узнали, как формы связаны с моделью Spring MVC. Мы также узнали, как отправлять запросы AJAX и частично обновлять представление.