Simple application of thmeleaf in springboot

Keywords: Thymeleaf Spring Fragment Session

Simple application of thmeleaf in springboot

The priority of static directory and the type of storage resources

Shortcut key of query class: ctrl+shift+r
Search ResourceProperties

private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
 new String[]{



Resource storage

resource: store uploaded resources
static: store css and pictures
Public: store public resources such as js

Simple application

Official website address of thymeleaf:

A simple html on the official website


<html xmlns=""

    <title>Good Thymes Virtual Grocery</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" media="all" 
          href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />

    <p th:text="#{home.welcome}">Welcome to our grocery store!</p>


Bring in namespace

Xmlns: shorthand for XML namespace
An error may be reported when a namespace is introduced. You can delete xmlns="", just use xmlns: th = ""


Some syntax of thymeleaf

  • Simple expression:
    Variable expression: ${ }
    Select variable expression: * { }
    Message expression: }
    Link URL expression: @ { }
  • Written words
    Text text: 'one text', 'Another one!'
    Number text: 0, 34, 3.0, 12.3
    Boolean text: true, false
    Empty text: null
    Text mark: one, sometext, main
  • Text operation:
    String concatenation:+
    Replace text with: "|The name is ${name}"|
  • Arithmetic operation:
    Binary operators: +, -, *, /,%
    Minus sign (unary operator):-
  • Boolean operation:
    Binary operators: and, or
    Boolean negation (unary operator):!, not
  • Comparison and equality:
    Comparison: >
    Equal sign operator: = =,! = (eq, ne)
  • Conditional operator:
    If - then: (if)? (then)
    If - then - otherwise: (if)? (then): (else)
    Default: (value)?: (DefaultValue)

Introduce css address

Above mentioned link URL expression: @ { }

	<!-- Bootstrap core CSS -->
	<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
	<!-- Custom styles for this template -->
	<link th:href="@{/css/signin.css}" rel="stylesheet"/>


This is in the doc on the official website

This is about Spring MVC and Thymeleaf: how to access data from templates:

In a typical Spring MVC application, the @ Controller class is responsible for preparing model diagrams with data and selecting the views to render. This model diagram allows for a complete abstraction of view technology, and in the case of Thymeleaf, it is transformed into a Thymeleaf context object (part of the execution context of the Thymeleaf template), which makes all defined variables available to expressions executed in the template.


  • Spring model attributes
  • Request parameters
  • Session attributes
  • ServletContext attributes
  • Spring beans(@Bean)

Let's talk about model properties

Refer to the document for details:


Create the i18n folder in the resources directory (i18n international abbreviation)
Take the landing page as an example

  • Create the file
  • Create the login ABCD file
  • Automatically generate Resource Bundle 'login' folder
  • Click Resource Bundle view
  • Click + to create
  • Input content in default, Chinese and English respectively
  • Binding internationalized content in a page

<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>

Translation between Chinese and English

index.html page Chinese English conversion a tag

	<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">Chinese</a>
	<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>

Chinese English mutual transfer configuration

Search webmvcauautoconfiguration
Refer to MessageCodesResolver method override

 public MessageCodesResolver getMessageCodesResolver() {
            if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
                DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
                return resolver;
            } else {
                return null;

Process the request parameters about the language from the request

package com.common.config;

import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

public class MyLocalResolver implements LocaleResolver {
    //Parsing request
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //Get language parameters in the request
        String language = httpServletRequest.getParameter("l");
        Locale locale = Locale.getDefault();        //If the default is not used
        //If the requested language parameter is not empty
        if(!StringUtils.isEmpty(language)) {
           String[] split = language.split("_");
           //Country, region
            locale = new Locale(split[0],split[1]);
        return locale;

    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {


Register LocaleResolver in the custom MyWebmvcConfig

package com.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

public class MyWebmvcConfig implements WebMvcConfigurer {
    public void addViewControllers(ViewControllerRegistry registry) {

    //Custom internationalization components
    public LocaleResolver localeResolver() {
        return new MyLocalResolver();

index.html code

<!DOCTYPE html>
<html lang="en" xmlns:th="">
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
	<meta name="description" content=""/>
	<meta name="author" content=""/>
	<title>Signin Template for Bootstrap</title>
	<!-- Bootstrap core CSS -->
	<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
	<!-- Custom styles for this template -->
	<link th:href="@{/css/signin.css}" rel="stylesheet"/>

<body class="text-center">
<form class="form-signin" action="dashboard.html">
	<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72"/>
	<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
	<label class="sr-only" th:text="#{login.username}">Username</label>
	<input type="text" class="form-control" th:placeholder="#{login.username}"  required="" autofocus=""/>
	<input type="password" class="form-control" th:placeholder="#{login.password}"  required=""/>
	<div class="checkbox mb-3">
			<input type="checkbox"  value="remember-me"/> [[#{login.remember}]]
	<button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.btn}]]</button>
	<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
	<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">Chinese</a>
	<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>



DOM selector syntax

according to vue Put forward the idea of public page thymeleaf Can also do
th:fragment="topbar" //Extract head navigation bar
th:fragment="sidebar" //Extract sidebar
th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}" //Control highlighting
th:replace="~{commons/commons::topbar}" //Import the header navigation bar from commons.html
th:replace="~{commons/commons::sidebar(active='main.html')}" //Introduce sidebar and pass value to commons.html to control highlight


<!DOCTYPE html>
<html lang="en"

<!-- Head navigation bar-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
    <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="">[[${session.loginUser}]]</a>
    <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
    <ul class="navbar-nav px-3">
        <li class="nav-item text-nowrap">
            <a class="nav-link" href="">Sign out</a>

<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
    <div class="sidebar-sticky">
        <ul class="nav flex-column">
            <li class="nav-item">
                <a th:class="${active=='main.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}">
                    <svg xmlns="" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home">
                        <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                        <polyline points="9 22 9 12 15 12 15 22"></polyline>
                    Dashboard <span class="sr-only">(current)</span>
            <li class="nav-item">
                <a class="nav-link" href="">
                    <svg xmlns="" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart">
                        <circle cx="9" cy="21" r="1"></circle>
                        <circle cx="20" cy="21" r="1"></circle>
                        <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
            <li class="nav-item">
                <a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}">
                    Staff management

dashboard.html import

//Part of code
<!--	Top navigation bar-->
<div th:replace="~{commons/commons::topbar}"></div>
<!--	sidebar-->
<div th:replace="~{commons/commons::sidebar(active='main.html')}"></div>

list.hmtl introduction

//Part of code
<!--Head navigation bar-->
<div th:replace="~{commons/commons::topbar}"></div>
<div th:replace="~{commons/commons::sidebar(active='list.html')}"></div>
59 original articles published, praised 0, and 629 visitors
Private letter follow

Posted by elhelaly1999 on Thu, 13 Feb 2020 22:41:24 -0800