Re learn the integration of static resources and template engine of SpringBoot series

Re learn the integration of static resources and template engine of SpringBoot series

webjars and static resources

spring boot static resources

Static resource directory

Under the default configuration of SpringBoot, the following static resource directories are provided:

/static:   classpath:/static/
/public:  classpath:/public/
/resources:  classpath:/resources/
/META-INF/resources: classpath:/META-INF/resources/

Of course, you can specify the location of static files through the spring.resources.static-locations configuration. However, it should be noted that once you specify a static resource directory, the system default static resource directory will become invalid. Therefore, the system default is enough. Try not to customize it.

#Configure static resources
spring:
  resources:
    #Specify static resource directory
    static-locations: classpath:/mystatic/

favicon.ico Icon

If there is a favicon.ico file in the configured static resource directory, SpringBoot will automatically set it as an application icon.

Welcome page

SpringBoot supports static and template welcome pages. It first looks at the index.html file in the static resource directory as the home page. If it is not found, it looks for the index template.

Managing css&js using WebJars

Why use WebJars?

Obviously, because it's simple. But it's not just dependency:

  • Clear management of web dependencies
  • web dependencies can be downloaded through Maven, Gradle and other project management tools
  • Solve the problem of transferring dependency and version in web components
  • Automatic version detection function of page dependency

Webjars packages these general Web front-end resources into Java Jar packages, and then manages them with the help of Maven tools to ensure the uniqueness of these Web resources and easy upgrade. There is a special website about webjars resources https://www.webjars.org/ , we can find the resources we need on this website, add maven dependency to our project, and then we can use these resources directly.

1. Introducing dependency in POM

We can view maven dependencies from WebJars official, as shown below

For example, introduce bootstrap and jquery into the pom file

<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>jquery</artifactId>
   <version>3.5.1</version>
</dependency>
<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>bootstrap</artifactId>
   <version>4.5.0</version>
</dependency>

2. Access the imported js file

The following methods can be used to access static resources in html:

<script src="/webjars/jquery/3.5.1/jquery.min.js "></script>
<script src="/webjars/bootstrap/4.5.0/js/bootstrap.min.js"></script>

Automatically detect dependent versions

If you use spring version 4.2 or above and add webjars locator component, you don't need to fill in the version when adding dependencies to html.

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator</artifactId>
    <version>0.30</version>
</dependency>

After introducing the webjars locator value, you can omit the version number:

<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>

Note: you can only remove the version number. The advantage is that when you upgrade the webjar version, you don't have to modify the version number of each file that introduces webjar.

In short, webjars can uniformly manage the front-end resources in the form of jar packages, which saves the trouble of downloading the front-end resource files and putting them under the static resource directory

And when you want to replace the version, you don't need to delete all the static resource files of the old version and introduce a new version. You can change the version in maven package management before

test

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
    <div class="container"><br/>
        <div class="alert alert-success">
            <strong>success!</strong>bootstrap webjar Perfect!
        </div>
    </div>


    <script src="/webjars/jquery/jquery.min.js "></script>
    <script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

Display effect: alert success of bootstrap

Template engine selection and future trend

Several stages of java web Development

jsp development phase

There are still many enterprise projects developed using jsp. It can be said that jsp is a servlet on the page side. jsp file combines three elements: Java code, dynamic data and HTML code structure. At the abstract level, the Java code part is not only used to organize data, but also used to control the structure of HTML pages. In this way, the hierarchy is relatively vague. Of course, enterprises can limit it in a standardized way and are not allowed to write java code on jsp pages, but this is only a matter at the normative level and can not be controlled in practice.

Using java template engine

At this stage, a template engine with strict data model and business code separation such as freemaker and velocity appears. The strict separation of MVC is realized. Another advantage of template engine is that macro definition or component template is easier to use than JSP tag, which greatly reduces the development of repeated page component elements. In addition, compared with JSP, the development efficiency of template engine will be higher. We all know that JSP needs to be converted into Servlet class when it is first executed. During function adjustment in the development stage, JSP needs to be modified frequently. Each modification needs to be compiled and converted. Then imagine how much time we waste in program compilation in a day.

However, the java template engine still uses the server-side rendering technology, that is, there is no way to completely decouple the html page from the background service level, which requires the front-end engineer and the back-end engineer to work under the same project structure, and the front-end engineer and the back-end engineer depend on the back-end business data, The page cannot run independently of the back-end request data in the browser.

Front end Engineering

After the emergence of ajax and nodejs, it can be said that it has brought revolutionary changes to the development of the front end. The front end can do its own engineering practice. These new front-end technologies are usually "what you see is what you get". The written code can be viewed directly on the browser, transforming the serial working mode of the front-end and back-end into a parallel working mode. The front end focuses on layout and beautification, and the back end focuses on business. Professional people are more and more professional and more efficient.

With the popularity of VUE, angularjs and reactjs, we began to realize the real front and rear end separation technology. The front-end engineer is responsible for the beautification and structure of the page, and the back-end engineer can focus on it It is applicable to business processing.

java template engine selection.

Common template engines include Freemarker, Thymeleaf, Velocity, etc. Let's talk about them respectively.

At present, the official integration framework of spring boot is only freemaker and thymeleaf. The official clearly suggests to give up velocity. Many people say thymeleaf is an official recommended template engine. To be honest, I can't find the source of this statement.

Thymeleaf:

The biggest advantage and disadvantage of Thymeleaf is that it uses static html to embed tag attributes. The browser can directly open the template file for front and rear joint debugging. That is, close to "what you see is what you get". However, because thyme uses tag attributes to put data, its syntax violates the programmer's understanding of html. In addition, the performance of Thymeleaf has been criticized.

Compare Thymeleaf code with the following code that freemaker traverses an object array:

<tr th:each="item : ${users}">
    <td th:text="${item.userId}"> </td>
    <td th:text="${item.username}"> </td>
    <td th:text="${item.password}"> </td>
    <td th:text="${item.email}"> </td>
    <td th:text="${item.mobile}"> </td>
</tr>

FreeMarker Code:

<#list users as item>
    <tr>
        <td>${item.userId}</td>
        <td>${item.username}</td>
        <td>${item.password}</td>
        <td>${item.email}</td>
        <td>${item.mobile}</td>
    </tr>
</#list>

Obviously, FreeMarker is more in line with the developers' specifications for HTML, and puts the display content in the tag rather than as a tag attribute. At this point, personally, ThymeLeaf is completely out of my consideration. In addition, the performance of ThymeLeaf 2.0 is very poor and criticized by people. Although ThymeLeaf 3.0 has improved, it has not changed subversively.

last

To sum up, so far, if you use java template engine, I still recommend freemaker. Of course, I have another suggestion. Learn from front-end frameworks such as LayUI, vue, angularjs and reactjs. Don't use pure java template engine. These things will be used less and less.

The above figure is Baidu Index, and the popularity of technology is clear at a glance!

Integrated jsp for web application development

Integrating JSPS through Maven coordinates

JSP needs the following three dependencies to provide a running environment

  • The embedded Tomcat container, spring boot starter web, contains spring boot starter tomcat, so it does not need to be introduced separately.
  • Tomcat embedded Jasper is mainly used to support the parsing and running of JSP.
  • jstl, which provides Java Web developers with a standard and general tag library. Developers can use these tags to replace java code written on JSP pages, so as to improve the readability of the program and reduce the difficulty of program maintenance.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring boot built-in tomcat jsp support -->
<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--jsp Page usage jstl label-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>jstl</artifactId>
</dependency>

Configure JSP lookup location

We need to tell Spring Boot where to find JSP files when rendering pages through configuration

spring:
  mvc:
    view:
      suffix: .jsp
      prefix: /WEB-INF/jsp/

debug: true
  • spring.mvc.view.prefix indicates which directory the jsp file is in webapp
  • spring.mvc.view.suffix indicates what suffix the jsp ends with. It must be the directory under / WEB-INF /, otherwise we will report an error later.

This directory structure corresponds to the location specified in the configuration file. Do not put it wrong.

  • Static resources, such as pictures, are placed under the resources/static directory
  • The JSP file is placed under webapp.WEB-INF.jsp

Code test

@Controller
@RequestMapping("/template")
public class TemplateController {

    @Resource
    ArticleService articleService;

    @GetMapping("/jsp")
    public String index(String name, Model model) {

        List<ArticleVO> articles = articleService.getAll();

        model.addAttribute("articles", articles);

        //Template name, actual Directory: src/main/webapp/WEB-INF/jsp/jsptemp.jsp
        return "jsptemp";
    }
}

jsptemp.jsp

The text code is as follows

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
<table class="table">
    <tr>
        <td>author</td>
        <td>Tutorial name</td>
        <td>content</td>
    </tr>
    <c:forEach var="article" items="${articles}">
        <tr class="text-info">
            <td>${article.author}</td>
            <td>${article.title}</td>
            <td>${article.content}</td>
        </tr>
    </c:forEach>


</table>
<img src="/image/jsp.png">

<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>

Operation method test

visit: http://localhost:8888/template/jsp , because JSP doesn't support jar well, it needs to be tested one by one. The results are as follows:

  • Use the IDEA startup class to start the test. There is no problem
  • Use spring boot: Run - F pom.xml to test, no problem (maven startup)
  • Print it into a jar package and run it in Java jar mode, and the page reports an error
  • Print it into a war package and run it in the external tomcat. There is no problem

Therefore, at present, I can't run jsp applications in the form of jar package. At least I didn't succeed in the experiment.

Integration of web application development freemaker

Introduction to Freemarker

FreeMarker is a template engine, a general tool for generating text output based on templates, written in pure Java. Generally, the first impression of FreeMarker is to replace JSP, but unlike JSP, FreeMarker template can be used outside the Servlet container. You can use them to generate e-mail, configuration files, XML maps, and so on. Or you can directly generate HTML files and other files to be used as tools for automatic code generation.

The core capability of Freemarker as a page template engine is to fill the relevant syntax placeholders in the HTML based template with data, and then form an HTML file that can be rendered by the browser

integration

Firstly, freemaker is introduced into the project through maven coordinates. Because freemaker is a template engine supported by the Spring Boot parent project, it does not need to add a version number, and the version is uniformly managed by the parent project

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

Perform the following configuration in the application.yml global configuration file

spring:
  freemarker:
    cache: false # The cache configuration should be configured as false during the development phase because it is often changed
    suffix: .ftl # Template file suffix 
    charset: UTF-8 # Document code
    template-loader-path: classpath:/templates/  

If not, create a new static and templates folder

Code test

We only do a simple test here. The test content is: query the article data from the database table, and return the query result List to the front-end FreeMarker template page for data filling.

import com.zimug.boot.launch.model.ArticleVO;
import com.zimug.boot.launch.service.ArticleService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;

@Controller
@RequestMapping("/template")
public class TemplateController {

    @Resource
    ArticleService articleService;

    @GetMapping("/freemarker")
    public String index(Model model) {

        List<ArticleVO> articles = articleService.getAll();

        model.addAttribute("articles", articles);

        //Template name, actual Directory: resources/templates/fremarkertemp.ftl
        return "freemarkertemp";
    }
}

The core content of the FreeMarker template page is to traverse the list data with < #list articles as article >. (other contents such as HTML and webjars are not the core contents of this section)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <table class="table">
            <tr>
                <td>author</td>
                <td>Tutorial name</td>
                <td>content</td>
            </tr>

            <#list articles as article>
                <tr>
                    <td>${article.author}</td>
                    <td>${article.title}</td>
                    <td>${article.content}</td>
                </tr>
            </#list>
        </table>
    </div>

    <script src="/webjars/jquery/jquery.min.js "></script>
    <script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

FreeMarker online manual

Integration of web application development thymeleaf

Introduction to Thymeleaf

Thymeleaf is a server-side java template engine, which can process HTML, XML, CSS, JAVASCRIPT and other template files. Thymeleaf template can be directly used as a static prototype. Its main goal is to bring elegant natural templates to developers' development workflow. It is also an ideal choice for Java server-side HTML5 development

Preparatory work - IDEA settings

Before starting to use ThymeLeaf as a template engine for page development, we need to make some settings for IDEA. These settings help IDEA better recognize ThymeLeaf syntax and enhance our development experience

  • Install the ThymeLeaf plug-in and make it effective (in most IDEA versions, the plug-in is installed and effective by default)
  • Removing the variable expression identification check will cause the variable to be underlined in red and affect the development experience

integrate

Introduce thymeleaf into the project using Maven coordinates

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Configure thymeleaf template

spring:
  thymeleaf:
    cache: false # Enable cache: it is recommended to enable production
    check-template-location: true # Check whether the template exists
    enabled: true # Enable
    encoding: UTF-8 # Template code
    excluded-view-names: # A comma separated list of view names that should be excluded from resolution
    mode: HTML5 # Template Pattern 
    prefix: classpath:/templates/ # Template storage path
    suffix: .html # Template suffix

Hello ThymeLeaf

After the example is completed, the project code structure is as follows:

Query a list of articles articles and return the template name. Spring finds the template according to the name for page rendering

import com.zimug.boot.launch.model.ArticleVO;
import com.zimug.boot.launch.service.ArticleService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.List;

@Controller
@RequestMapping("/template")
public class TemplateController {

    @Resource
    ArticleService articleService;

    @GetMapping("/thymeleaf")
    public String index(Model model) {

        List<ArticleVO> articles = articleService.getAll();

        model.addAttribute("articles", articles);

        //Template name, actual Directory: resources/templates/thymeleaftemp.html
        return "thymeleaftemp";
    }
}

New thymeleaf template page: thymeleaf template.html.

  • Note that this xmlns:th attribute must be added.
  • Note: th:each is thymelaef, and its core function is collection traversal
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
</head>
<body>

<div class="container">
    <table class="table">
        <tr>
            <td>author</td>
            <td>Tutorial name</td>
            <td>content</td>
        </tr>

        <tr th:each="item : ${articles}">
            <td th:text="${item.author}"></td>
            <td th:text="${item.title}"></td>
            <td th:text="${item.content}"></td>
        </tr>
    </table>
</div>


<script src="/webjars/jquery/jquery.min.js "></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>

</body>
</html>

Basic grammar explanation of thymeleaf

Basic grammar

Variable expression ${}

Usage: directly use th:xx = "${}" to obtain object properties. For example, articles is a collection, the element in the collection is an object, and articles[0] represents the first object in the collection

<div th:text="hello"></div>
<form id="articleForm">
    <input id="id" name="id" th:value="${articles[0].id}"/>
    <input id="author" name="author" th:value="${articles[0].author}"/>
    <input id="content" name="content" th:value="${articles[0].content}"/>
</form>

Select variable expression * {}

Usage: first obtain the object through th:object, and then obtain the object attribute using th:xx = "* {}". The display effect is the same as the above example.

<form id="articleForm" th:object="${articles[0]}">
    <input id="id" name="id" th:value="*{id}"/>
    <input id="author" name="author" th:value="*{author}"/>
    <input id="content" name="content" th:value="*{content}"/>
</form>

Link expression @{}

Usage: get the application path through the link expression @{} directly, and then splice the static resource path. For example:

<link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">

<script th:src="@{/webjars/jquery/jquery.min.js} "></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>

The actual effect of introducing html pages is as follows (this method will expose the version number of webjars and cause security problems to a certain extent, so do not use link expressions when using webjars):

Other expressions

In the basic syntax, string connection, mathematical operation, Boolean logic and ternary operation are supported by default. For example:

<div th:text="${'I am '+(articles[0].author!=null?articles[0].author:'NoBody')}"></div>

When articles[0].author is not null, it displays: dhy; otherwise, it displays: NoBody

Iterative cycle

It's easy to traverse the List set. You can quickly complete the iteration with th:each. However, we usually have some requirements. We can also obtain state variables in the iterative process of the set. The status variable can be used to obtain the subscript / sequence number, total number, whether it is an odd / even row, and whether it is the first / last row of the set. For example:

<table class="table">
    <tr>
        <td>subscript</td>
        <td>Serial number</td>
        <td>author</td>
        <td>Tutorial name</td>
        <td>content</td>
    </tr>

    <tr th:each="item,stat : ${articles}" th:class="${stat.even}?'even':'odd'">
        <td th:text="${stat.index}"></td>
        <td th:text="${stat.count}"></td>
        <td th:text="${item.author}"></td>
        <td th:text="${item.title}"></td>
        <td th:text="${item.content}"></td>
    </tr>
</table>

Iterative subscript variable usage:

State variables are defined in a th: each attribute and contains the following data:

  • Index: current iteration index, starting from 0. This is the index property.
  • count: current iteration sequence number, starting from 1. This is the ordinal attribute.
  • Size: the total iteration variable of the element. This is the size attribute.
  • current: the variable is the element of each iteration that is currently being iterated
  • even/odd: whether the current iteration is odd or even, Boolean attribute.
  • First: whether to the first current iteration, Boolean attribute.
  • Last: whether the last current iteration, Boolean attribute.

Inter row color change of the table, that is, color change of odd rows, is realized through stat.even. Set the background color separately for odd rows

<style type="text/css">
    .odd{
        background-color: #7d7d7d;
    }
</style>

Conditional judgment

Condition judgment is usually used for initialization of dynamic pages, for example:

<div th:if="${articles}">
    <div>Article list exists</div>
</div>

The conditional judgment expression can be of the following types:

  • boolean type and the value is true, return true
  • Value type and value is not 0, return true
  • If the character type (Char) and the value is not 0, return true
  • String type, and the value is not "false", "off", "no", return true
  • Not boolean, numeric, character, other types of String, return true
  • Object value is null, return false

If you want to reverse, use unless, for example:

<div th:unless="${articles}">
    <div>No article list.</div>
</div>

thymeleaf built-in objects and tool classes

Built in object

Thymeleaf 3.0 official website

Seven basic objects:

  • ${#ctx} context object, which can be used to get other built-in objects.
  • ${#param}: context parameter variable.
  • ${#locale}: context locale object.
  • ${#request}: HttpServletRequest object.
  • ${#response}: HttpServletResponse object.
  • ${#session}: HttpSession object.
  • ${#servletContext}: ServletContext object.

Usage example

To demonstrate the data, we use different object containers when passing parameters from the backend to the thymeleaf template. Note the parameter names in the following figure: name1, name2, name3, name4.

The corresponding code shown in the figure above:

@GetMapping("/thymeleaf")
public String index(@RequestParam String name1,
                    HttpServletRequest request,
                    Model model) {

    List<ArticleVO> articles = articleService.getAll();

    request.setAttribute("name2", "curry");
    request.getSession().setAttribute("name3", "james");
    request.getServletContext().setAttribute("name4","jordan");

    model.addAttribute("articles", articles);

    //Template name, actual Directory: resources/templates/thymeleaftemp.html
    return "thymeleaftemp";
}

Receive parameters in thymeleaf template

<h1>ThymeLeaf Built in object</h1>
<br/>Language country:    <span th:text="${#locale.getLanguage() + '_' + #locale.getCountry()}"></span>
<br/>param:      <span th:text="${param.name1}"></span>
<br/>request:     <span th:text="${name2}"></span>
<br/>session:    <span th:text="${session.name3}"></span>
<br/>application: <span th:text="${application.name4}"></span>
<br/>session contain name3 Property (if not included) zoo): <span th:text="${session.name3}?:('zoo')"></span>
<br/>session Number of attributes included:<span th:text="${session.size()}"></span>
<br/>session Is it empty:<span th:text="${session.isEmpty()}"></span>

visit: http://localhost:8888/template/thymeleaf?name1=dhy , notice the name1 parameter in the URL

Common tools:

Built in object

  • #strings: String utility class
  • #lists: List utility class
  • #arrays: array utility class
  • #sets: Set tool class
  • #maps: common Map methods.
  • #objects: general object class, which is usually used to judge whether it is not empty
  • #bools: a common boolean method.
  • #execInfo: get the processing information of the page template.
  • #Messages: the method of obtaining external messages in variable expressions is the same as that obtained using {...} syntax.
  • #uris: method to escape partial URLs / uris.
  • #conversions: the method used to execute the configured conversion service.
  • #dates: time operation and time formatting.
  • #calendars: for formatting more complex times.
  • #numbers: method for formatting numeric objects.
  • #aggregates: method to create an aggregate on an array or collection.
  • #ids: method for handling potentially duplicate id attributes.

Usage example:

Date formatting of date tool class

Using the default date format (toString method) is not what we expected: Mon Dec 03 23:16:50 CST 2018

At this time, you can format the date through the time tool class #dates: 2018-12-03 23:16:50

<td th:text="${#dates.format(item.createTime,'yyyy-MM-dd HH:mm:ss')}"></td>

title case

${#strings.capitalizeWords(str)}         

list method

/*
 * Count the number of elements in the list collection
 */
${#lists.size(list)}

/*
 * Check whether the collection is empty
 */
${#lists.isEmpty(list)}

Public fragment (tag) and inline js

Fragment expression (label) ~ {}

The use process of fragment expression is a bit like that in our usual code development process: common function extraction. Let's start our study according to this idea!

Determine which code is reusable

The following head tag fragments exist on many pages, and most of the contents are consistent. What should we do if we want the contents in the head tag to be reused in each page? In this section, we will take you to solve the problem of component code reuse

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="'/webjars/bootstrap/4.5.0/css/bootstrap.min.css'">
    <style type="text/css">
        .odd{
            background-color: #7d7d7d;
        }
    </style>
</head>

Custom reusable code snippets

First, customize the code fragments through th:fragment. Usually, the frequently reused code in the project is extracted into code fragments (tags). The code fragments can set parameters: title and version

<!-- /templates/common/head.html-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head th:fragment="static(version,title)">
    <meta charset="UTF-8">
    <title th:text="${title}"></title>
    <link rel="stylesheet"
          th:href="'/webjars/bootstrap/'+ ${version} + '/css/bootstrap.min.css'">
    <style type="text/css">
        .odd{
            background-color: #7d7d7d;
        }
    </style>
</head>

Reference reusable code snippets

Then reference the fragment on different pages to achieve the purpose of code reuse. You can pass the parameters version and title

<head th:replace="~{common/head::static('4.5.0','Page title')}"></head>

The final reuse code combination effect is as follows:

Fragment expression is one of the features of Thymeleaf. The fine granularity can reach the tag level, which is impossible for JSP. Fragment expression has three syntax:

  • ~{viewName} indicates the introduction of a full page
  • ~{VIEWNAME:: selector} means to find fragments on the specified page, where the selector can be fragment name, jquery selector, etc., that is, multiple fragments can be defined in an html page
  • ~{:: selector} means to find code fragments in the current html page

Multiple fragment combinations

In practice, we tend to use more concise expressions, remove the expression shell and directly fill in the fragment name. For example:

<div th:replace="common/head::static"></div>
<div th:insert="common/head::static"></div>
<div th:include="common/head::static"></div>

The difference between thymeleaf th:replace th:include th:insert

  • th:replace: do not use your own master tag, but keep the master tag of th:fragment.
  • th:insert: keep its own main tag, and keep the main tag of th:fragment.
  • th:include: keep your own master tag, not the master tag of th:fragment. (not recommended after official 3.0)

It is worth noting that do not add slash / when using the replacement path th:replace to avoid path errors during deployment. (because the default splicing path is spring.thymeleaf.prefix = classpath:/templates /)

Inline syntax

What we talked about before is the syntax of thymeleaf used on html tags. What should we do if we need to get the value of variables in javascript (using the expression mentioned before)?

A: the standard format is: [${expression}]]. You can read server variables or call methods of built-in objects. For example, get user variables and application paths:

  <script th:inline="javascript">
        var user = [[${articles[0]}]];
        var APP_PATH = [[${#request.getContextPath()}]];
        var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
    </script>

The HTML page uses inline syntax, and the results are as follows:

Can inline expressions be used in JS introduced in tags (code fragments)? A: no! The inline expression only takes effect on the page, because Thymeleaf is only responsible for parsing the first level view and cannot recognize the expression in the external tag JS.

Added by sharyn on Tue, 07 Dec 2021 16:19:35 +0200