当前位置:网站首页>Template engine - thymeleaf

Template engine - thymeleaf

2022-06-11 11:31:00 Java rookie ~

1. Introduction to template engine

template engine ? You may have heard about template engines for the first time , I guess you can't help asking : What is a template engine ?

template engine ( This is especially for Web Developed template engine ), For user interface and business data ( Content ) The result of separation , It can generate documents in a specific format , The template engine for the site will generate a standard html file ;

  • Literally : The most important thing about the template engine is Templates Two words , It is equivalent to making a template and inserting the data in the corresponding position , With a final html Show it in the format of ;
  • After the template is designed, you can directly fill in the data , Without having to redesign the entire page , This improves the reusability of pages and code ;

2. Template engine and Thymeleaf Relationship

Java There are many template engines in , Template engine is the product of the development and progress of dynamic web pages , At the beginning and most popular jsp It's a template engine , But because of jsp There are many shortcomings , So many people abandon jsp Choose a third-party template engine , There are also many open source third-party template engines on the market , Yes Thymeleaf、FreeMaker、Velocity The template engine has a wide audience .

Use Thymeleaf advantage :

  • Dynamic and static separation :Thymeleaf Use html Its meaning is represented by some specific tag syntax , And did not destroy html structure , Even without the Internet 、 It can be opened successfully in the browser without back-end rendering , It greatly facilitates the testing and modification of the interface ;

Relationship :Thymeleaf Is one of the products of template engine !!!

3. Template engine principle

  • First : The client browser initiates HTTP Ask to servlet in ;
  • servlet Call template engine organization Templates ( Static resources )+ data ( Dynamic resources ), Splice the two together into one HTML character string ;
  • Will be HTML The string is returned to the server ;

4. Usage flow

Process 1 : adopt maven Introduce dependencies

  • stay maven Central warehouse search Thymeleaf And select a version ;

maven Central warehouse website :https://mvnrepository.com/

After entering , Search for Thymeleaf:
 Insert picture description here

  • choice 3.0.12 edition ;

 Insert picture description here

  • Copy dependent code to pox.xml And refresh ;

 Insert picture description here
At the same time, we need to use servlet, Therefore, we should also introduce servlet Dependency package ;

 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

Process 2 : establish HTML Template file

establish hello.html , Put it in webapp/WEB-INF/templates Directory ;

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
   <h3> Web template technology learning </h3>
   <p th:text="${message}"></p>
</body>
</html>

Process 3 : To write servlet Code

Operation steps

  • Create a template engine ;
  • Create a web page template parser ;
  • Set the encoding at render time ;
  • Set the prefix and suffix of the web page template file path ;
  • Bind the template parser to the template engine ;
  • Create a web Context ( Semantics of environment , Inside is map structure , Store key value pair data );
  • Set the data of key value pair ;
  • Returns the rendered web page string ;
package org.example;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/hello")

public class HelloServlet extends HttpServlet {
    
    // Template engines return HTML, So rewrite HTML
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
       // Set up body Format and coding format 
        resp.setContentType("text/html; charset = utf-8");

        //1. Create a template engine 
        TemplateEngine engine = new TemplateEngine();

        //2. Create a web page template parser 
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());

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

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

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

        //6. Create a web Context ( Semantics of environment , Inside is map structure , Can store key value pair data )
        WebContext webContext =new WebContext(req,resp,getServletContext());
        //7. Set the data of key value pair : It can be understood as : Defines a variable for the web page template ( A variable called message, The value is hello template engine )
        webContext.setVariable("message","hello template engine ");

        // The template engine renders web page templates : The first parameter is the template name , The second parameter is web Context ( It holds data )
        // According to the prefix set by the template parser + Template name + suffix , For template path , Found template , Then organize the template content + data 
        //8. The return value is the rendered web page string 
        String html =engine.process("hello",webContext);
        resp.getWriter().write(html);

    }
}

Process 4 : The deployment process

adopt URL

http://127.0.0.1:8080/Thymeleaf-study/hello

Access server , You can see the page display :
 Insert picture description here

here , The page still looks static , Make the following changes :

 // Here is the fixed page display 
  //webContext.setVariable("message","hello template engine ");
   // Set dynamically changing  msg=xxx
   webContext.setVariable("message", req.getParameter("msg"));

In this way, you can use the browser address bar URL Different input contents will produce different effects !

The code analysis

But above servlet Code , Execution efficiency is not high , And there is redundancy !
reason : Just send... Each time URL request : Will create a template engine and interpreter ;

Optimize the code

Place the created template engine and interpreter in init() In the method , This method is called only once !

package org.example;



import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/hello")


public class HelloServlet extends HttpServlet {
    

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

        //2. Create a web page template parser 
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());

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

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

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

    }

    // Template engines return HTML, So rewrite HTML
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
       // Set up body Format and coding format 
        resp.setContentType("text/html; charset = utf-8");

        // Create a web Context ( Semantics of environment , Inside is map structure , Can store key value pair data )
        WebContext webContext =new WebContext(req,resp,getServletContext());
        // Set the data of key value pair : It can be understood as : Defines a variable for the web page template ( A variable called message, The value is hello template engine )
        // Here is the fixed page display 
        //webContext.setVariable("message","hello template engine ");
        // Set dynamically changing  msg=xxx
        webContext.setVariable("message", req.getParameter("msg"));

        // The template engine renders web page templates : The first parameter is the template name , The second parameter is web Context ( It holds data )
        // According to the prefix set by the template parser + Template name + suffix , For template path , Found template , 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);

    }
}

5. Understand that only one engine instance is created ?

After the above optimization , There's another problem

When creating another Servlet when , You still need to create a TemplateEngine Instance and initialize , therefore , There are still multiple template engine objects and parser objects , But it is absolutely unnecessary !!!

In a complete project , Just create one TemplateEngine, And only initialize once ~

In order to achieve such a goal , You need to use Servlet Medium ServletContext and “ Monitor ”;

(1) ServletContext

ServletContext It's a Servlet The space in a program where information is stored globally , The server was there from the beginning , The server is down before it is destroyed ;

  • Tomcat When it starts , It will Web app Create a corresponding ServletContext;
  • One Web All in the application Servlet Share the same ServletContext object ;
  • Can pass HttpServlet.getServletContext() perhaps HttpServletRequest.getServletContext() Get to the current webapp Of ServletContext object ;

The relationship shown below

 Insert picture description here
ServletContext An important method of object :

Method function
void setAttribute(String name,Object obj) Set properties ( The form of key-value pairs )
Object getAttribute(String name) Get the property value according to the property name , If name non-existent , return null
void removeAttribute(String name) Delete the corresponding attribute

Code example : Multiple servlet Shared data

(1) Create a writeServlet class ;

package org.example;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/write")
public class writeServlet extends HttpServlet {
    
    // write?data=xxx
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    

        String data = req.getParameter("data");
        // Write data to servlet Shared context 
        // Get current servletContext object 
        ServletContext sc = getServletContext();
        // Set properties 
        sc.setAttribute("d",data);

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

(2) Create a readServlet class ;

package org.example;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/read")
public class readServlet extends HttpServlet {
    
    // write?data=xxx
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        
        // Get current servletContext object 
        ServletContext sc = getServletContext();
        // According to the property name , Get attribute value 
       Object data = sc.getAttribute("d");

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

(3) adopt ServletContext Data sharing ;

Access... Through the address bar URL:http://localhost:8080/Thymeleaf-study/write?data=shd, You can see the write success flag , stay http://localhost:8080/Thymeleaf-study/read Access the data that can be read and written ;

As shown below

 Insert picture description here
 Insert picture description here

(2) Monitor

Monitor : It belongs to a design pattern ;

Advantages of using a listener

  • Decouple the event and the code to be executed after the event ;
  • Register a function or method to the listener in advance , After an event , Automatic execution ;

Use steps

  • Create a class ;
  • add to @WebListener annotation , otherwise Tomcat Can't identify ;
  • Realization ServletContextListener Interface , And implement two methods contextInitialized and contextDestroyed;

The code is as follows

package org.example;


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener

public class MyListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
    
       
  }
  
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    

    }
}

(3) modify Thymeleaf Engine initialization code

package org.example;


import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener

public class MyListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
    
        //1.  First get context object 
        ServletContext context = sce.getServletContext();
        //2.  establish Templateengine object 
        TemplateEngine engine = new TemplateEngine();
        //3. Create parser object 
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(context);
        
        //4. Set up resolver Some properties of 
        resolver.setCharacterEncoding("utf-8");
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
       
        //5. binding  resolver  and  engine
        engine.setTemplateResolver(resolver);

        //6. take  engine  Put it in  ServletContext in , For others servlet Use 
        context.setAttribute("engine",engine);
  }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    

    }
}

Follow up Servlet Directly from ServletContext Get to the engine Object can ;

6. Thymeleaf Template syntax

(1) Common commands and functions

command function
th:text Display the text content of the expression evaluation result in the label body
th:[HTML Tag attributes ] Set up any HTML The value of the tag property
th:if When the result of the expression is true, the content is displayed , Otherwise it doesn't show
th:each Loop through elements

(2) Text labels

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

The final results : take webContext Set key value pair data , The key is message Set the value of to the label content ;

(3) Set tag properties

Common properties

  • href
  • src
  • class
  • style…

If setting link a Labeled href attribute :

The front-end code

 <a th:href="${a1}"> Baidu </a>
 <a th:href="${a2}"> sogou </a>

servlet Code

 package org.example;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/hello")


public class HelloServlet extends HttpServlet {
    

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

        //2. Create a web page template parser 
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(getServletContext());

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

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

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

    }

    // Template engines return HTML, So rewrite HTML
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
       // Set up body Format and coding format 
        resp.setContentType("text/html; charset = utf-8");

        // Create a web Context ( Semantics of environment , Inside is map structure , Can store key value pair data )
        WebContext webContext =new WebContext(req,resp,getServletContext());
        // Set the data of key value pair :

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

        // The template engine renders web page templates : The first parameter is the template name , The second parameter is web Context ( It holds data )
        // According to the prefix set by the template parser + Template name + suffix , For template path , Found template , 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);

    }
}

(4) conditional

  conditional  th:if : The condition determines whether the label displays ;
 <p th:if="${islogin}"> Already logged in </p>

When webContext.setVariable("islogin",true); The value passed in is true when , It is displayed as : Already logged in , Otherwise it doesn't show ;

Web page shows
 Insert picture description here

(5) loop

       th:each  Loop constructs multiple elements ;
 <ul>
       <li th:each="name : ${names}">
            <span th:text="${name}"></span>
      </li>
  </ul>
  webContext.setVariable("names", Arrays.asList(" Zhang San "," Li Si "," Wang Wu "));

The web page shows the results
 Insert picture description here

原网站

版权声明
本文为[Java rookie ~]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203012157329466.html