- Создатель Васильев Антон, отредактировано 29.12.2023
Вы просматриваете старую версию данной страницы. Смотрите текущую версию.
Сравнить с текущим просмотр истории страницы
« Предыдущий Версия 7 Следующий »
Основные правила
Метка в шаблоне
Метка в шаблоне обозначается ${…}. Метка заменяется значением выражения внутри фигурных скобок. Примеры: ${1 + 2}, ${variableName}
Теги
Теги FTL похожи на теги HTML (но содержат # или @ ), и FreeMarker интерпретирует их, например, <#if…></#if>
Комментарии
Комментарии в FreeMarker начинаются с <#– и заканчиваются -->
Статус | В РАБОТЕ |
---|---|
Раздел | Freemarker |
Операторы
Оператор | Описание |
---|---|
?? | Проверить существует ли атрибут или вложенное свойство |
?c | Преобразовать логическое значение в удобочитаемую строку |
! | Значение по умолчанию, если атрибут не существует |
() | Проверить существует ли атрибут и имеет ли он вложенное свойство с другим вложенным свойством |
Пример
<p>Testing is student property exists: ${student???c}</p> <p>Using default value for missing student: ${student!'John Doe'}</p> <p>Wrapping student nested properties: ${(student.address.street)???c}</p>
<p>Testing is student property exists: false</p> <p>Using default value for missing student: John Doe</p> <p>Wrapping student nested properties: false</p>
Тег «если-иначе»
Управляющие структуры присутствуют во FreeMarker, и традиционный if-else
<#if condition> <!-- block to execute if condition is true --> <#elseif condition2> <!-- block to execute if condition2 is the first true condition --> <#elseif condition3> <!-- block to execute if condition3 is the first true condition --> <#else> <!-- block to execute if no condition is true --> </#if>
Пример
<#if status??> <p>${status.reason}</p> <#else> <p>Missing status!</p> </#if>
<!-- When status attribute exists --> <p>404 Not Found</p> <!-- When status attribute is missing --> <p>Missing status!</p>
Контейнеры подпеременных
Во FreeMarker есть три типа контейнеров для подпеременных:
- Хэши - это последовательность пар ключ-значение — ключ должен быть уникальным внутри хеша
- Последовательности - это списки, в которых у нас есть индекс, связанный с каждым значением — примечательным фактом является то, что подпеременные могут быть разных типов.
- Коллекции - это особый случай последовательностей, где мы не можем получить доступ к размеру или получить значения по индексу — мы все же можем перебирать их с помощью тега списка <#list>
Повторение элементов
Перебор контейнера двумя основными способами.
<#--Перебираем каждое значение, и для каждого из них выполняется логика--> <#list sequence as item> <!-- do something with ${item} --> </#list> <#--Или, когда мы хотим повторить Hash , получая доступ как к ключу, так и к значению --> <#list hash as key, value> <!-- do something with ${key} and ${value} --> </#list>
<#-- Позволяет определить логику, которая должна происходить на различных этапах итерации. Элемент представляет собой имя зацикленной переменной, но можно переименовать его по своему усмотрению --> <#list sequence> <!-- one-time logic if the sequence is not empty --> <#items as item> <!-- logic repeated for every item in sequence --> </#items> <!-- one-time logic if the sequence is not empty --> <#else> <!-- one-time logic if the sequence is empty --> </#list>
Пример
<#list statuses> <ul> <#items as status> <li>${status}</li> </#items> </ul> <#else> <p>No statuses available</p> </#list>
<ul> <li>200 OK</li> <li>404 Not Found</li> <li>500 Internal Server Error</li> </ul>
Обработка предметов
Хэш позволяет выполнять две простые функции: keys для извлечения только содержащихся ключей и values для извлечения только значений.
Последовательность более сложная; можно сгруппировать наиболее полезные функции:
- фрагмент и соединение , чтобы получить подпоследовательность или объединить две последовательности
- reverse , sort и sortBy для изменения порядка элементов
- first и last извлекут первый или последний элемент соответственно
- size представляет количество элементов в последовательности
- seqContains , seqIndexOf или seqLastIndexOf для поиска элемента
Обработка типов
FreeMarker поставляется с огромным количеством разнообразных функций (встроенных), доступных для работы с объектами. Давайте посмотрим на некоторые часто используемые функции.
Обработка строк
- url и urlPath будут экранировать строку URL-адресом, за исключением того, что urlPath не будет экранировать косую черту /
- jString , jsString и jsonString будут применять правила экранирования для Java, Javascript и JSON соответственно .
- capFirst , uncapFirst , upperCase , lowerCase и capitalize полезны для изменения регистра строки, как следует из их названий.
- boolean , date , time , datetime и number - это функции для преобразования строки в другие типы.
Пример
<p>${'http://myurl.com/?search=Hello World'?urlPath}</p> <p>${'Using " in text'?jsString}</p> <p>${'my value?upperCase}</p> <p>${'2019-01-12'?date('yyyy-MM-dd')}</p>
<p>http%3A//myurl.com/%3Fsearch%3DHello%20World</p> <p>MY VALUE</p> <p>Using \" in text</p> <p>12.01.2019</p>
Обработка чисел
- round , min и max могут помочь с округлением чисел
- abs вернет абсолютное значение числа
- string преобразует число в строку. Мы также можем передать четыре предопределенных числовых формата: компьютер , валюта , число или процент или определить свой собственный формат, например ["0.###"]
Пример
<p>${(7.3?round + 3.4?ceiling + 0.1234)?string('0.##')}</p> <#-- (7 + 4 + 0.1234) with 2 decimals -->
<p>11.12</p>
Обработка даты
- .now представляет текущую дату и время
- date , time и datetime могут возвращать разделы даты и времени объекта даты и времени.
- строка преобразует дату и время в строки - можно передать желаемый формат или использовать предопределенный
<p>${.now?time?string('HH:mm')}</p>
<p>15:39</p>
Обработка исключений
Два способа обработки исключений для шаблона FreeMarker.
Первый способ — использовать теги попытки восстановления
, чтобы определить, что мы должны попытаться выполнить, и блок кода, который должен выполниться в случае ошибки.
<#attempt> <!-- block to try --> <#recover> <!-- block to execute in case of exception --> </#attempt>
Теги попытки
и восстановления
являются обязательными. В случае ошибки он откатывает предпринятый блок и выполняет только код в разделе восстановления
.
Помня об этом синтаксисе, давайте определим наш шаблон как:
<p>Preparing to evaluate</p>
<#attempt>
<p>Attribute is ${attributeWithPossibleValue??}</p>
<#recover>
<p>Attribute is missing</p>
</#attempt>
<p>Done with the evaluation</p>
Когда attributeWithPossibleValue
отсутствует, мы увидим:
<p>Preparing to evaluate</p>
<p>Attribute is missing</p>
<p>Done with the evaluation</p>
И вывод, когда attributeWithPossibleValue
существует:
<p>Preparing to evaluate</p>
<p>Attribute is 200 OK</p>
<p>Done with the evaluation</p>
Второй способ — настроить FreeMarker, что должно происходить в случае исключений.
С Spring Boot мы легко настраиваем это через файл свойств; вот некоторые доступные конфигурации:
spring.freemarker.setting.template_exception_handler=rethrow
повторно выдает исключениеspring.freemarker.setting.template_exception_handler=debug
выводит клиенту информацию о трассировке стека, а затем повторно выдает исключение.spring.freemarker.setting.template_exception_handler=html_debug
выводит клиенту информацию о трассировке стека, форматируя ее так, чтобы она обычно хорошо читалась в браузере, а затем повторно выдает исключение.spring.freemarker.setting.template_exception_handler=ignore
пропускает ошибочные инструкции, позволяя шаблону продолжить выполнение.spring.freemarker.setting.template_exception_handler = по умолчанию
9. Методы вызова
Иногда мы хотим вызывать методы Java из наших шаблонов FreeMarker. Сейчас мы посмотрим, как это сделать.
9.1. Статические члены
Чтобы начать доступ к статическим членам, мы можем либо обновить нашу глобальную конфигурацию FreeMarker, либо добавить в модель атрибут типа S taticModels
под именем атрибута statics
:
model.addAttribute("statics", new DefaultObjectWrapperBuilder(new Version("2.3.28"))
.build().getStaticModels());
Доступ к статическим элементам прост.
Сначала мы импортируем статические элементы нашего класса, используя тег assign, затем выбираем имя и, наконец, путь к классам Java.
Вот как мы импортируем класс Math
в наш шаблон, показываем значение статического поля PI
и используем статический метод pow :
<#assign MathUtils=statics['java.lang.Math']>
<p>PI value: ${MathUtils.PI}</p>
<p>2*10 is: ${MathUtils.pow(2, 10)}</p>
Результирующий HTML:
<p>PI value: 3.142</p>
<p>2*10 is: 1,024</p>
9.2. Члены бина
Доступ к членам компонента очень прост: используйте точку (.) , и все!
В нашем следующем примере мы добавим в нашу модель объект Random :
model.addAttribute("random", new Random());
В нашем шаблоне FreeMarker сгенерируем случайное число:
<p>Random value: ${random.nextInt()}</p>
Это приведет к выводу, подобному:
<p>Random value: 1,329,970,768</p>
9.3. Пользовательские методы
Первым шагом для добавления пользовательского метода является наличие класса, который реализует интерфейс TemplateMethodModelEx
FreeMarker и определяет нашу логику внутри метода exec :
public class LastCharMethod implements TemplateMethodModelEx {
public Object exec(List arguments) throws TemplateModelException {
if (arguments.size() != 1 || StringUtils.isEmpty(arguments.get(0)))
throw new TemplateModelException("Wrong arguments!");
String argument = arguments.get(0).toString();
return argument.charAt(argument.length() - 1);
}
}
Мы добавим экземпляр нашего нового класса в качестве атрибута модели:
model.addAttribute("lastChar", new LastCharMethod());
Следующим шагом будет использование нашего нового метода внутри нашего шаблона:
<p>Last char example: ${lastChar('mystring')}</p>
Наконец, в результате получается:
<p>Last char example: g</p>
- Нет меток