Оглавление

2 Хорошая виртуальная бакалейная лавка Thymes


Исходный код примеров, показанных в этом и будущих главах руководства, можно найти в репозитории Good Thymes Virtual Grocery GitHub https://github.com/thymeleaf/thymeleafexamples-gtvg.

2.1 Вебсайт для бакалейной лавки


Чтобы лучше объяснить концепции, связанные с обработкой шаблонов с помощью Thymeleaf, в этом учебнике будет использоваться демонстрационное приложение, которое вы можете загрузить с веб-сайта проекта.

Это приложение является веб-сайтом воображаемого виртуального бакалейного магазина и предоставит нам множество сценариев, чтобы продемонстрировать многие функции Thymeleaf.

Для начала нам нужен простой набор объектов-моделей для нашего приложения: Продукты, которые продаются Клиентам через Заказы. Мы также будем управлять комментариями о продуктах:

Пример моделей приложения

Наше приложение также будет иметь очень простой сервис уровень, состоящий из объектов Service, содержащих такие методы, как:

public class ProductService {
    ...
    public List<Product> findAll() {
        return ProductRepository.getInstance().findAll();
    }

    public Product findById(Integer id) {
        return ProductRepository.getInstance().findById(id);
    }
}

На веб-уровне наше приложение будет иметь фильтр, который делегирует выполнение команд с поддержкой Thymeleaf в зависимости от URL-адреса запроса:

private boolean process(HttpServletRequest request, HttpServletResponse response)
        throws ServletException {
    
    try {
        // This prevents triggering engine executions for resource URLs
        if (request.getRequestURI().startsWith("/css") ||
                request.getRequestURI().startsWith("/images") ||
                request.getRequestURI().startsWith("/favicon")) {
            return false;
        }

        /*
         * Query controller/URL mapping and obtain the controller
         * that will process the request. If no controller is available,
         * return false and let other filters/servlets process the request.
         */
        IGTVGController controller = this.application.resolveControllerForRequest(request);
        if (controller == null) {
            return false;
        }

        /*
         * Obtain the TemplateEngine instance.
         */
        ITemplateEngine templateEngine = this.application.getTemplateEngine();

        /*
         * Write the response headers
         */
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        /*
         * Execute the controller and process view template,
         * writing the results to the response writer. 
         */
        controller.process(
                request, response, this.servletContext, templateEngine);
        
        return true;
        
    } catch (Exception e) {
        try {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } catch (final IOException ignored) {
            // Just ignore this
        }
        throw new ServletException(e);
    }
}

Интерфейс нашего контроллера IGTVGController:

public interface IGTVGController {
    public void process(
            HttpServletRequest request, HttpServletResponse response,
            ServletContext servletContext, ITemplateEngine templateEngine);    
    
}

Все, что осталось сделать — это реализовать интерфейс IGTVGController, запрашивающий данные из сервисов и обрабатывающий шаблоны с помощью объекта ITemplateEngine.

В конце это будет выглядеть так:

Пример домашней страницы приложения

2.2 Создание и конфигурирование Template Engine


Метод process(…) в нашем фильтре содержит эту строку:

ITemplateEngine templateEngine = this.application.getTemplateEngine();

Это означает, что класс GTVGApplication отвечает за создание и настройку одного из наиболее важных объектов в приложении Thymeleaf: экземпляр TemplateEngine (реализация интерфейса ITemplateEngine).

Наш объект org.thymeleaf.TemplateEngine инициализируется:

public class GTVGApplication {
    ...
    private final TemplateEngine templateEngine;
    ...
    public GTVGApplication(final ServletContext servletContext) {

        super();

        ServletContextTemplateResolver templateResolver = 
                new ServletContextTemplateResolver(servletContext);
        
        // HTML is the default mode, but we set it anyway for better understanding of code
        templateResolver.setTemplateMode(TemplateMode.HTML);
        // This will convert "home" to "/WEB-INF/templates/home.html"
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        // Template cache TTL=1h. If not set, entries would be cached until expelled by LRU
        templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
        
        // Cache is set to true by default. Set to false if you want templates to
        // be automatically updated when modified.
        templateResolver.setCacheable(true);
        
        this.templateEngine = new TemplateEngine();
        this.templateEngine.setTemplateResolver(templateResolver);
        ...
    }
}

Существует множество способов настройки объекта TemplateEngine, но на данный момент эти несколько строк кода будут достаточно подробно информировать нас о необходимых шагах.

The Template Resolver

Давайте начнем с Template Resolver:

ServletContextTemplateResolver templateResolver = 
        new ServletContextTemplateResolver(servletContext);

Template Resolvers являются объектами, которые реализуют интерфейс из Thymeleaf API, называемый org.thymeleaf.templateresolver.ITemplateResolver:

public interface ITemplateResolver {
    ...
    /*
     * Templates are resolved by their name (or content) and also (optionally) their 
     * owner template in case we are trying to resolve a fragment for another template.
     * Will return null if template cannot be handled by this template resolver.
     */
    public TemplateResolution resolveTemplate(
            final IEngineConfiguration configuration,
            final String ownerTemplate, final String template,
            final Map<String, Object> templateResolutionAttributes);
}

Эти объекты отвечают за определение того, как будут доступны шаблоны, и в этом приложении GTVG org.thymeleaf.templateresolver.ServletContextTemplateResolver означает, что мы собираемся извлекать файлы шаблонов в качестве ресурсов из контекста сервлета: на уровне приложения javax.servlet.ServletContext, который существует в каждом веб-приложении Java, и который разрешает ресурсы из корня веб-приложения.

Но это еще не все, что мы можем сказать о распознавателе шаблона, потому что мы можем установить на нем некоторые параметры конфигурации. Во-первых, режим шаблона:

templateResolver.setTemplateMode(TemplateMode.HTML);

HTML — это режим шаблонов по умолчанию для ServletContextTemplateResolver, но это хорошая практика, чтобы установить его в любом случае, чтобы наши документы кода четко указывали, что происходит.

templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");

Префикс и суффикс изменяют имена шаблонов, которые мы передадим движку для получения имен реальных ресурсов, которые будут использоваться.

Используя эту конфигурацию, имя шаблона «product/list» будет соответствовать:

servletContext.getResourceAsStream("/WEB-INF/templates/product/list.html");

Необязательно, но количество времени, в течение которого анализируемый шаблон может проживать в кеше, настраивается в Template Resolver с помощью свойства cacheTTLMs:

templateResolver.setCacheTTLMs(3600000L);

Шаблон все еще может исчезнуть из кеша до достижения TTL, если достигнут максимальный размер кеша, и это самая старая запись.

Поведение и размеры кэша могут быть определены пользователем путем реализации интерфейса ICacheManager или путем изменения объекта StandardCacheManager для управления кешем по умолчанию.

Можно еще сказать много слов о template resolvers, но давайте вернемся к созданию нашего объекта Template Engine.

Template Engine

Объекты Template Engine — это реализация интерфейса org.thymeleaf.ITemplateEngine. Одна из этих реализаций предлагается ядром Thymeleaf: org.thymeleaf.TemplateEngine, и мы создаем его экземпляр:

templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);

Просто, не так ли? Все, что нам нужно, это создать экземпляр и установить для него template resolvers.

Template resolvers является единственным обязательным параметром, требуемым TemplateEngine, хотя есть много других, которые будут рассмотрены позже (message resolvers, размеры кеша и т. Д.). Пока что это все, что нам нужно.

Наш шаблонный модуль теперь готов, и мы можем начать создавать страницы с помощью Thymeleaf.

Продолжение. Глава 3. Использование Text

Комментарии (4)


  1. capjdcoder
    12.03.2018 01:42

    А как быть с масштабированием и нагрузкой? Не проще использовать на стороне клиента Angular/React/Vue для отрисовки чем каждый раз гонять сервер для вывода страничек?


    1. pilot911 Автор
      12.03.2018 10:30

      в Thymeleaf используется кэширование, а так же возможна ситуация, когда на клиент подгружается не чистый JSON, а так же отрендеренный HTML — тут тоже нужен шаблонизатор


  1. mikaakim
    12.03.2018 10:03

    А чем эта статья отличается от документации и какова её полезная нагрузка?


    1. pilot911 Автор
      12.03.2018 10:28

      мне кажется, документация должна переводиться, так раскрываются нюансы