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 и частично обновлять представление.

