📜 ⬆️ ⬇️

Thymeleaf Tutorial: Chapter 2. A Thymes Good Virtual Grocery Store

Table of contents

2 Good virtual grocery store by Thymes


The source code for the examples shown in this and future chapters can be found in the Good Thymes Virtual Grocery GitHub repository at https://github.com/thymeleaf/thymeleafexamples-gtvg .

2.1 Grocery Store Website


To better explain the concepts involved in processing templates with Thymeleaf, this tutorial will use a demo application that you can download from the project website.
')
This app is an imaginary virtual grocery web site and will provide us with many scripts to demonstrate the many features of Thymeleaf.

First, we need a simple set of model objects for our application: Products that are sold to Customers through Orders. We will also manage comments about products:

Sample Application Models

Our application will also have a very simple service level, consisting of Service objects containing methods such as:

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

At the web level, our application will have a filter that delegates the execution of commands with Thymeleaf support depending on the request 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); } } 

The interface of our controller IGTVGController:

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

All that remains to be done is to implement the IGTVGController interface, requesting data from services and processing templates using the ITemplateEngine object.

In the end it will look like this:

Sample application home page

2.2 Creating and Configuring the Template Engine


The process (...) method in our filter contains this line:

 ITemplateEngine templateEngine = this.application.getTemplateEngine(); 

This means that the GTVGApplication class is responsible for creating and configuring one of the most important objects in the Thymeleaf application: the TemplateEngine instance (implementation of the ITemplateEngine interface).

Our org.thymeleaf.TemplateEngine object is initialized:

 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); ... } } 

There are many ways to customize a TemplateEngine object, but at the moment these few lines of code will inform us in sufficient detail about the necessary steps.

The template resolver

Let's start with Template Resolver:

 ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext); 

Template Resolvers are objects that implement an interface from the Thymeleaf API, called 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); } 

These objects are responsible for determining how templates will be available, and in this GTVG application, org.thymeleaf.templateresolver.ServletContextTemplateResolver means that we are going to retrieve the template files as resources from the servlet context: at the javax.servlet.ServletContext application level that exists in every Java web application, and which resolves resources from the root of the web application.

But this is not all that we can say about the pattern recognizer, because we can set some configuration parameters on it. First, the template mode:

 templateResolver.setTemplateMode(TemplateMode.HTML); 

HTML is the default template mode for the ServletContextTemplateResolver, but it is a good practice to install it anyway so that our code documents clearly state what is happening.

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

The prefix and suffix change the names of the templates that we pass to the engine to get the names of the actual resources to be used.

Using this configuration, the template name “product / list” will match:

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

Optional, but the amount of time that the analyzed template can live in the cache is configured in the Template Resolver using the cacheTTLMs property:

 templateResolver.setCacheTTLMs(3600000L); 

The template can still disappear from the cache before reaching the TTL, if the maximum cache size is reached, and this is the oldest entry.

The behavior and cache sizes can be defined by the user by implementing the ICacheManager interface or by modifying the StandardCacheManager object to manage the default cache.

There are many more words to say about template resolvers, but let's go back to creating our Template Engine object.

Template engine

Template Engine objects are an implementation of the org.thymeleaf.ITemplateEngine interface. One of these implementations is offered by the Thymeleaf core: org.thymeleaf.TemplateEngine, and we create an instance of it:

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

Simple, isn't it? All we need is to create an instance and set up a template resolvers for it.

Template resolvers is the only required parameter required by TemplateEngine, although there are many others that will be discussed later (message resolvers, cache sizes, etc.). So far this is all we need.

Our template module is now ready, and we can start creating pages with Thymeleaf.

Continued. Chapter 3. Using Text

Source: https://habr.com/ru/post/350866/


All Articles