В прошлой статье я показывал, как генерировать статические веб страницы с помощью Spring Wev MVC и отдавать их браузеру. Тот пример был основан на довольно старой технологии JSP, которая хоть и поддерживается, но её использование крайне неудобно и может вызвать преждевременную деменцию.
Современная альтернатива JSP — шаблонизаторы. Идея в общем-то таже самая: вы пишете html код в который в разных местах вставляете метки для установки переменных. Перед выдачей страницы по запросу вы берёте шаблон, записываете значения в переменные и отдаёте их шаблонизатору, который подставляет значения в шаблон и генерирует финальную страницу.
FreeMarker, один из современных шаблонизаторов, весьма богатый возможностями, гибкий и надёжный. К сожалению в этой статье я не смогу описать особенности самого FreeMarker, но согу написать о поддержке FreeMarker в Spring Web MVC. Для примера я перепишу код из статьи о JSP с использованием FreeMarker
Настройка FreeMarker
Чтобы включить FreeMarker в Spring Boot, необходимо добавить следующую зависимость к проекту:
1
2
3
4
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
|
Добавление этого стартера к сборке автоматически включит поддержку FreeMarker в SpringBoot. По умолчанию шаблоны должны располагаться в каталоге /resources/templates и иметь суффикс .ftl Имя файла совпадает с именем вида, так же как и в случае с JSP (и с другими view технологиями, которые поддерживает Spring Web MVC)
Шаблоны
Весь Java код, за исключением не требующейся здесь конфигурации JSP, совершенно идентичен коду предыдущего примера и, как мне кажется, нет смысла его повторять. Отличие же только в шаблонах. В частности шаблон вывода списка, /resources/templates/list.ftl теперь выглядит несколько иначе:
1
2
3
4
5
6
7
8
9
10
11
|
<html>
<head><title>List of parcels</title></head>
<body>
<h1>Parcels list</h1>
<ul>
<#list parcels as parcel>
<li><a href="/packages/${parcel.id}">Owner: <b>${parcel.owner}</b>, weight: <b>${parcel.weight}</b> kg</a>
</#list>
</ul>
</body>
</html>
|
Это всё тот же HTML, только уже без JSP преамбулы в заголовке и с более лаконичными тегами, которые, на мой взгляд, даже более понятные.
Что же касается форм, то они тоже работают, но требуется определённая поддержка со стороны Spring:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<#import "/spring.ftl" as spring/>
<html>
<head><title>Parcel for ${parcel.owner}</title></head>
<body>
<h1>Parcel for ${parcel.owner}</h1>
<form action="" method="POST">
<table>
<tr>
<td>Owner:</td>
<td>
<@spring.bind "parcel.owner"/>
<input type="text" name="${spring.status.expression}" value="${spring.status.value?html}"/>
</td>
</tr>
<tr>
<td>Weight:</td>
<td>
<@spring.bind "parcel.weight"/>
<input type="text" name="${spring.status.expression}" value="${spring.status.value?html}"/>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save Changes"/></td>
</tr>
</table>
</form>
</body>
</html>
|
Для поддержки форм необходимо загрузить Spring макрос и вызывать его для каждого поля формы, чтобы связать это поле со свойством модели. Можно использовать макросы вида @spring.formInput, чтобы, как и в JSP, автоматически генерировать поля для форм.
Код примера доступен на github.