Understanding template engine Thymeleaf

What is a template engine?

[function] the template engine is created to separate the user interface from the business data (content). It can separate the Servlet Java code and Html web page code (this is the advantage of the template engine compared with the Servlet directly returning to the dynamic page)

Principle / process

Thymeleaf usage process

Thymeleaf is a template engine in Java, which is the most popular one at present

1. Introduce dependency through maven

stay maven central warehouse Search Thymeleaf

Select an appropriate version, such as 3.0.12

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.12.RELEASE</version>
</dependency>

After introducing dependencies, be sure to refresh the Maven panel
Note: web projects need to be packaged in war format - < packaging > war < / packaging >

2. Create Html template file

Create hello HTML, put it in webapp / WEB-INF / templates directory

<h3 th:text="${message}"></h3>

give an example:

<body>
    <h3>Web template technology learning</h3>
    <p th:text="${message}"></p>
</body>

You will find that there is red:


th:text is the syntax of Thymeleaf, and the browser cannot directly recognize the th:text attribute

3. Write Servlet code

  1. Create a template engine and a web page template parser
  2. Set render time encoding
  3. Set the prefix and suffix of web page template file and path
  4. Bind the template parser to the template engine
  5. Create a web context (the semantics of the environment, which contains the map structure and stores key value pair data)
  6. Set data of key value pair
  7. Returns the rendered web page string to the response body
@WebServlet("/hello")
public class helloServlet extends HttpServlet {
    // Generally, the url is entered in the browser address bar to access the web page, which is the get method
    // All template engines return html, so override doGet
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        // Using thymeleaf template technology
        // Create a template engine
        TemplateEngine engine = new TemplateEngine();

        // Create a parser for the web page template: getServletContext() is a method in HttpServlet that returns the Servlet context object
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());

        // Sets the encoding at render time
        resolver.setCharacterEncoding("utf-8");

        // Set the prefix and suffix of web page template file and path
        resolver.setPrefix("/WEB-INF/templates/"); // prefix
        resolver.setSuffix(".html");  // suffix

        // Bind the template parser to the template engine
        engine.setTemplateResolver(resolver);

        // Create a web context (the semantics of the environment, in which there is a map structure that can store the data of key value pairs)
        WebContext webContext = new WebContext(req,resp,getServletContext());
        // Set a key value pair data, which can be understood as: define a variable for the web page template, the variable name is message, and the value is "hello template engine"
        // queryString pass in msg=xxx
        webContext.setVariable("message",req.getParameter("msg"));

        // The template engine renders the web page template: the first parameter is the template name, and the second parameter is the Web context (in which the data is saved)
        // According to the prefix + template name + suffix set by the template parser For the template path, find the template, and then organize the template content + data
        // The return value is the rendered web page string
        String html = engine.process("hello",webContext);
        resp.getWriter().write(html);
    }
}

Start the service and refresh the page:

Each request creates a template engine and a web page template parser, which is inefficient and unnecessary. We can rewrite an init method because init only executes once, while doGet method executes every request. You can put the code for creating template engine and web page template parser into init method

@Override
public void init() throws ServletException {
    // Create a template engine
    TemplateEngine engine = new TemplateEngine();

    // Create a parser for the web page template: getServletContext() is a method in HttpServlet that returns the Servlet context object
    ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());
    // Sets the encoding at render time
    resolver.setCharacterEncoding("utf-8");

    // Set the prefix and suffix of web page template file and path
    resolver.setPrefix("/WEB-INF/templates/"); // prefix
    resolver.setSuffix(".html");  // suffix

    // Bind the template parser to the template engine
    engine.setTemplateResolver(resolver);

}

However, at this time, you will find that the code will be red:


Set templateengine = new templateengine(); Put it outside the init() method, i.e

Restart, refresh page:
(efficiency improved)

Thymeleaf common template syntax

commandfunction
th: textThe text content of the expression evaluation result is displayed in the label body
th: [HTML tag attribute]Set the value of any HTML tag attribute
th: ifWhen the result of the expression is true, the content will be displayed; otherwise, it will not be displayed
th: eachCircular access element

${variable name} to refer to the key value pair data set in Java code (${key} is the value)

Note: the absolute path of the website still needs to add http: / /, which needs to be written in full
give an example:

webContext.setVariable("a1","http://www.baidu.com");

Understand that only one engine instance is created

The entire web application only needs to be initialized once (the objects engine and resolver in the code only need to be created once)
(reason: objects and attributes will not change). In the previous part of the article, an improved method is also proposed, which is put in the init() method of Servlet

But there are still problems: each Servlet needs to be created in the init method. In a webapp, there are still many engine and resolver objects
Each Servlet class that needs to render a page needs to create a TemplateEngine instance and initialize it. In fact, it is completely unnecessary!

In a complete project, you only need to create a TemplateEngine and initialize it only once
In order to improve the above problems, ① ServletContext and ② "listener" in Servlet need to be used

ServletContext

ServletContext is a global information storage space in the Servlet program. The server exists from the beginning and is destroyed only after the server is shut down

As shown in the following figure:

  • When Tomcat starts, it will create a corresponding ServletContext for each webapp
  • All servlets in a Web application share the same Servlet Context object
  • You can use httpservlet Getservletcontext() or HttpServletRequest Getservletcontext() gets the ServletContext object of the current webapp

Understanding Context: Context / environment; It is often used to set some data into the Context; Objects in the Context can refer to each other's data (Context is a semantic concept in many places)

Namely:
Data cannot be transferred directly between multiple servlets, but some data can be set / used through a shared context (data transfer)
ServletContext is similar to Map structure, which stores multiple sets of key value pair data

Important methods of ServletContext object

methoddescribe
void setAttribute(String name, Objectobj)Set properties (key value pairs)
Object getAttribute(String name)Get the property value according to the property name. If the name does not exist, return null
void removeAttribute(String name)Delete the corresponding attribute

You can see that Servlet Context is very similar to HttpSession class. It also organizes several key value pair structures internally, which is equivalent to a hash table; At this time, multiple servlets can share the same data through webcontext

Code example: multiple servlets share data

1) Create ContextWriteServlet class

@WebServlet("/write")
public class ContextWriteServlet extends HttpServlet {

    // write?data=xxx
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String data = req.getParameter("data");
        // Write data to the context of Servlet sharing
        ServletContext sc = getServletContext();
        sc.setAttribute("d",data);

        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("write in Context success!");
    }
}

2) Create ContextReadServlet class

@WebServlet("/read")
public class ContextReadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Write data to the context of Servlet sharing
        ServletContext sc = getServletContext();
        Object data = sc.getAttribute("d");

        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("read Context:" + data);
    }
}

Start the service and open the page:

If we do not access / write but directly access / read, the data obtained at this time is null:

Listener listener

A listener belongs to a design mode

For example, as I learned earlier, in html / js, bind an event (event registration) for a DOM element. There is no need to call the function of the event manually, but the browser calls the function bound by the event when the event occurs
This "event" is actually the design pattern of the listener
If it is a code with strong coupling, we may execute it; The above example is the code to be executed when an event occurs, which is decoupled from the event occurrence

During the operation of Servlet, there will be some special "opportunities" for us to execute some custom logic
The listener is to allow the program ape to "insert code" at these special times

Summary of listener advantages:

  • Decouple the event and the code to be executed after the event
  • Register a function or method to the listener in advance and execute it automatically after an event occurs

Code example: listen for the creation of ServletContext

Steps:

  • First create a class
  • Add @ WebListener annotation modification, otherwise Tomcat cannot recognize it
  • Implement the ServletContextListener interface, and implement two methods contextInitialized and contextDestroyed
@WebListener
public class MyListener implements ServletContextListener {
@WebListener
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // This will be called when the context is created
        // The creation time is before all servlets are instantiated
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // This will be called when the context is destroyed
    }
}

Keywords: Java servlet

Added by prakash911 on Thu, 10 Mar 2022 08:53:45 +0200