[JAVA] Comment utiliser Thymeleaf avec Spring Boot

Qu'est-ce que Thymeleaf

Environnement d'exploitation

Enquêter sur l'hypothèse qu'il fonctionnera en tant que moteur de modèle de vue de Spring MVC sur Spring Boot.

Hello World

build.gradle


buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE'
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-devtools'
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
}

ext['thymeleaf.version'] = '3.0.7.RELEASE'
ext['thymeleaf-layout-dialect.version'] = '2.2.2'

jar.baseName = 'thymeleaf'

Structure des dossiers


|-build.gradle
`-src/main/
  |-java/sample/thymeleaf/
  |  |-Main.java
  |  `-web/
  |    `-HelloController.java
  |
  `-resources/
    |-application.properties
    `templates/
       `-hello.html

application.properties


spring.thymeleaf.mode=HTML

--Par défaut, il fonctionne en mode HTML5

Main.java


package sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello Thymeleaf!!");
        return "hello";
    }
}

--Avec les paramètres par défaut de Spring Boot, les fichiers de modèle sont recherchés dans / resources / templates / [Controller return value] .html sous le chemin de classe.

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <h1 th:text="${message}"></h1>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

Intégration de texte

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <h1 th:text="'hello world'"></h1>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

hello.html


<h1 th:text="'hello world'"></h1>

Traitement en ligne

hello.html


<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <h1>[['hello world!!']]</h1>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Avec [[[valeur à afficher]]], vous pouvez afficher la valeur directement sur le modèle sans utiliser th: text.

Sortie des variables

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("modelValue", "Model Value!!");
        return "hello";
    }
}

hello.html


<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <h1>[[${modelValue}]]</h1>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

hello.html


<h1>[[${modelValue}]]</h1>

--Utilisez l'expression $ {[nom de la variable]} pour incorporer la valeur stockée dans le contexte d'exécution dans le modèle.

HelloControlloer.java


    public String hello(Model model) {
        model.addAttribute("modelValue", "Model Value!!");

--L'enregistrement de la valeur dans le contexte se fait en recevant la classe Model comme argument de contrôleur de Spring MVC et en utilisant la méthode ʻaddAttribute ()`.

Syntaxe d'expression

littéral

<!--Chaîne-->
<span th:text="'some text'"></span>
<!--Valeur numérique-->
<span th:text="123"></span>
<!--Valeur booléenne-->
<span th:text="true"></span>
<!-- null -->
<span th:text="null"></span>

Concaténation de chaînes

<span th:text="'some text' + '!!'"></span>

Remplacement littéral

<span th:text="|Hello ${message}|"></span>

Opérateur arithmétique

<span th:text="(30 * 20 + 10 / 5 - 1) % 3"></span>

--*,/,+, '-', '%' peuvent être utilisés

Opérateur logique

<span th:text="true
                and false
                or true
                and not true
                or !false"></span>

Equivalent à la comparaison

<span th:text="1 < 10"></span>
<span th:text="1 > 10"></span>
<span th:text="1 <= 10"></span>
<span th:text="1 >= 10"></span>
<span th:text="1 == 10"></span>
<span th:text="1 != 10"></span>

-- <,> ,<=,> = peuvent être utilisés --Chacun est le même que l'opérateur Java --==,! = Est remplacé par une comparaison utilisant ʻequals ()` (la comparaison de chaînes est également possible)

Opérateur conditionnel

1: <span th:text="true ? 'a'"></span><br>
2: <span th:text="false ? 'b'"></span><br>
3: <span th:text="true  ? 'c': 'C'"></span><br>
4: <span th:text="true ?: 'd'"></span><br>
5: <span th:text="false ?: 'e'"></span><br>
6: <span th:text="null ?: 'f'"></span><br>

** Résultat de sortie **

thymeleaf.jpg

** [Condition]? [Valeur] **

** [Condition]? [Valeur 1]: [Valeur 2] **

-Si [Condition] est "true", [Value 1] est évaluée, et si elle est "false", [Value 2] est évaluée.

** [Objet]?: [Valeur] **

Expression SpEL

L'intérieur de $ {...} est évalué par un langage d'expression appelé SpEL (Spring Expression Language). Avec ce SpEL, vous pouvez facilement accéder aux objets.

Le langage d'expression standard est OGNL

En regardant la simple référence Thymeleaf, il est dit que OGNL est utilisé comme langage d'expression. Cependant, lorsqu'il est intégré à Spring, SpEL sera utilisé à la place.

Tutorial: Thymeleaf + Spring

2 The SpringStandard Dialect

Use Spring Expression Language (Spring EL or SpEL) as a variable expression language, instead of OGNL. Consequently, all ${...} and *{...} expressions will be evaluated by Spring’s Expression Language engine.

(Traduction) Utilisez Spring Expression Language (Spring EL ou SpEL) comme langage d'expression pour les variables au lieu de OGNL. Par conséquent, toutes les expressions $ {...} et * {...} sont évaluées par le moteur de langage d'expression de Spring.

Référence de méthode de propriété de champ

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("hoge", new Hoge());
        return "hello";
    }
    
    public static class Hoge {
        public int publicField = 1;
        
        public int publicMethod() {return 2;}
        
        public int getPublicValue() {return 3;}
    }
}
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <div th:text="${hoge.publicField}"></div>
        <div th:text="${hoge['publicField']}"></div>
        <div th:text="${hoge.publicMethod()}"></div>
        <div th:text="${hoge.publicValue}"></div>
        <div th:text="${hoge['publicValue']}"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

Référence cartographique

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.HashMap;

@Controller
public class HelloController {
    
    @GetMapping("/hello")
    public String hello(Model model) {
        HashMap<String, String> map = new HashMap<>();
        map.put("message", "Hello World!!");

        model.addAttribute("map", map);
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <div th:text="${map.message}"></div>
        <div th:text="${map['message']}"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Pour Map, vous pouvez faire référence à la valeur avec map. Key.

Référence de liste

HelloConteroller.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("list", Arrays.asList(1, 2, 3));
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <div th:text="${list[0]}"></div>
        <div th:text="${list[1]}"></div>
        <div th:text="${list[2]}"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Pour accéder à List et aux éléments d'un tableau, utilisez list [index]

Définir une valeur pour un attribut

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <span th:class="'hello' + 'world'">hoge</span>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

URL du lien

application.properties


server.contextPath=/thymeleaf

--Définissez Spring Boot pour commencer avec le chemin de contexte pour vérifier le fonctionnement

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li>
                @{foo/bar} = [[@{foo/bar}]]
            </li>
            <li>
                @{/foo/bar} = [[@{/foo/bar}]]
            </li>
            <li>
                @{~/foo/bar} = [[@{~/foo/bar}]]
            </li>
            <li>
                @{http://localhost:8080/foo/bar} = [[@{http://localhost:8080/foo/bar}]]
            </li>
            <li>
                @{//localhost:8080/foo/bar} = [[@{//localhost:8080/foo/bar}]]
            </li>
        </ul>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

type La description
foo/bar Chemin relatif normal
/foo/bar Chemin relatif à partir du chemin de contexte
~/foo/bar Chemin relatif depuis la racine du serveur (/fooDevient un autre chemin de contexte)
http://xxx/xxx Chemin absolu
//xxx/xxx Chemin relatif du protocole

Normalement, il est spécifié dans l'attribut href de la balise <a>, donc

<a th:href="@{/foo/bar}">/foo/bar</a>

Il sera défini comme suit.

Définir les paramètres de requête

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("paramValue", "PARAM VALUE");
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        [[@{/foo/bar(hoge='HOGE', paramValue=${paramValue})}]]
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

Incorporer des variables dans le chemin

hello.html


<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        [[@{/foo/{pathValue}/bar(pathValue=123)}]]
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

Objets pouvant être référencés implicitement

En plus de la valeur définie dans le contrôleur Model, il existe des objets auxquels il est possible d'accéder par défaut.

<span th:text="${#httpServletRequest}"></span>
<span th:text="${#httpSession}"></span>
<span th:text="${param}"></span>
<span th:text="${session}"></span>
<span th:text="${application}"></span>

-- # httpServletRequest est l'objet HttpServletRequest lui-même -- # httpSession fait référence à l'objet HttpSession lui-même --param est l'objet qui contient les paramètres de la requête --session est les informations d'attribut stockées dans HttpSession --ʻApplicationest les informations d'attribut stockées dansServletContext --param, session, ʻapplication peuvent être référencés comme`` Map --param ['nom_paramètre'] `etc.

Différence avec et sans «#»

--httpServletRequest est préfixé par#, pas session ou param

Sélection d'objets

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("hoge", new Hoge());
        return "hello";
    }
    
    public static class Hoge {
        public String name = "hogeee";
        public String value = "HOGEEE";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <div th:object="${hoge}">
            <div>name = [[*{name}]]</div>
            <div>value = [[*{value}]]</div>
        </div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

hello.html


        <div th:object="${hoge}">
            <div>name = [[*{name}]]</div>
            <div>value = [[*{value}]]</div>
        </div>

--Si vous spécifiez un objet avec th: object, vous pouvez vous référer directement aux champs et propriétés de cet objet sous la forme` * {} ʻ dans les éléments enfants de cette balise.

Déclaration des variables locales

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <div th:with="message = 'Hello World!!'">
            message = [[${message}]]
        </div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

hello.html


        <div th:with="message = 'Hello World!!'">
            message = [[${message}]]
        </div>

Basculement entre l'affichage et le non-affichage selon les conditions

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("flag", true);
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <h1 th:if="${flag}">flag is true</h1>
        <h1 th:if="${!flag}">flag is false</h1>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Si vous utilisez th: if =" [condition] ", il ne sera affiché que lorsque [condition] est ** une valeur évaluée à true **.

Valeur évaluée comme vrai / faux

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("booleanTrue", true);
        model.addAttribute("booleanFalse", false);
        model.addAttribute("numericZero", 0);
        model.addAttribute("numericOne", 1);
        model.addAttribute("charZero", '0');
        model.addAttribute("stringEmpty", "");
        model.addAttribute("stringZero", "0");
        model.addAttribute("stringOff", "off");
        model.addAttribute("stringNo", "no");
        model.addAttribute("stringFalse", "false");
        model.addAttribute("anyObject", new Object());
        model.addAttribute("nullValue", null);
        
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li th:if="${booleanTrue}">booleanTrue</li>
            <li th:if="${booleanFalse}">booleanFalse</li>
            <li th:if="${numericZero}">0</li>
            <li th:if="${numericOne}">numericOne</li>
            <li th:if="${charZero}">charZero</li>
            <li th:if="${stringEmpty}">stringEmpty</li>
            <li th:if="${stringZero}">stringZero</li>
            <li th:if="${stringOff}">stringOff</li>
            <li th:if="${stringNo}">stringNo</li>
            <li th:if="${stringFalse}">stringFalse</li>
            <li th:if="${anyObject}">anyObject</li>
            <li th:if="${nullValue}">nullValue</li>
        </ul>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

** Valeur évaluée comme fausse </ font> **

--booléen faux --Numérique 0

  • null --String " false ", " off ", " no "

** Valeur évaluée comme vraie </ font> **

--Tout sauf "valeur évaluée comme fausse" --Exemple -- vrai de booléen --Nombre «1» --String " 0 "

  • Caractères vides --Tout objet qui n'est pas «nul»

Quand je lis la référence, il est dit, "Les valeurs autres que" 0 "" dans la chaîne sont évaluées comme "vrai". " En d'autres termes, il semble que "" "0" ʻ de la chaîne de caractères soit évalué comme "faux" ", mais quand il est réellement essayé, il est évalué comme" vrai ". punaise?

Traitement itératif

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("list", Arrays.asList("hoge", "fuga", "piyo"));
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li th:each="element : ${list}">[[${element}]]</li>
        </ul> 
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--th: each = "[Nom de la variable pour stocker chaque élément]: $ {[Objet à itérer]}" , les balises peuvent être générées à plusieurs reprises

  • [Nom de la variable pour stocker chaque élément] devient une variable valide uniquement en sortie répétée
  • Si la classe implémente ʻIterable, elle peut être traitée de manière itérative avec th: each`.

Répéter la carte

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.HashMap;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        HashMap<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        model.addAttribute("map", map);
        
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li th:each="entry : ${map}">
                key=[[${entry.key}]], value=[[${entry.value}]]
            </li>
        </ul>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Lorsque Map est traité de manière itérative, Map.Entry est traité de manière itérative comme chaque élément.

Lors du traitement répété autre que List et Map

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li th:each="element : 'text'">[[${element}]]</li>
        </ul>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--Si un objet autre que Map qui n'implémente pas ʻIterable est traité de manière itérative avec th: each, il est traité comme une List` qui n'a que cette valeur.

Référence d'état répétitif

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("list", Arrays.asList("hoge", "fuga", "piyo"));
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <ul>
            <li th:each="element, status : ${list}">
                index = [[${status.index}]],
                count = [[${status.count}]],
                size = [[${status.size}]],
                current = [[${status.current}]],
                even = [[${status.even}]],
                odd = [[${status.odd}]],
                first = [[${status.first}]],
                last = [[${status.last}]]
            </li>
        </ul>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

--th: each = "[chaque élément], [variable d'état]: [cible répétée]" , en ajoutant, nom de variable après la déclaration de chaque variable d'élément, l'état de chaque boucle peut être changé. Vous pourrez utiliser les variables conservées --Si vous omettez la déclaration de la variable d'état, la variable d'état est préparée avec la variable nommée «[chaque élément] Stat». --Si vous définissez th: each =" element: $ {list} ", vous pouvez vous référer à la variable status avec ʻelementStat`. --Status contient des informations sur l'état actuel de la boucle

  • Les informations stockées dans l'état sont les suivantes
Nom de variable sens
index Index de la boucle actuelle (0Début)
count Nombre de boucles actuel (1Début)
size Taille de l'objet à répéter
current Élément répétitif actuel
even Si l'élément actuel est pair (valeur vraie / fausse)
odd Si l'élément actuel est impair (valeur vraie / fausse)
first Si l'élément actuel est le premier (valeur vraie / fausse)
last Si l'élément actuel est à la fin (valeur vraie / fausse)

th:block

HelloController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("list", Arrays.asList("hoge", "fuga", "piyo"));
        
        return "hello";
    }
}

hello.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Thymeleaf</title>
    </head>
    <body>
        <th:block th:each="element : ${list}">
            <h2>[[${element}]]</h2>
        </th:block>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

hello.html


        <th:block th:each="element : ${list}">
            <h2>[[${element}]]</h2>
        </th:block>
  • La balise <th: block> est complètement effacée après le rendu
  • Le traitement des feuilles de thymeleaf (th: if, etc.) peut être écrit, il n'est donc pas nécessaire d'augmenter la balise <div> juste pour écrire le traitement.

Incorporer un fragment

Incorporer d'autres modèles

Structure des dossiers


`-src/main/
  |-java/sample/thymeleaf/
  | `-FragmentController.java
  |
  `-resources/templates/fragment/
    |-fragment.html
    `-embedded.html

FragmentController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class FragmentController {
    
    
    @GetMapping("/fragment")
    public String fragment() {
        return "fragment/fragment";
    }
}

embedded.html


<h2>embedded</h2>

fragment.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Fragment</title>
    </head>
    <body>
        <h1>Hello Fragment</h1>
        <div id="foo"
             th:insert="fragment/embedded"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

Structure des dossiers


`-src/main/
  `-resources/templates/fragment/
    |-fragment.html
    `-embedded.html

fragment.html


        <div id="foo"
             th:insert="fragment/embedded"></div>

--Utilisez th: insert pour intégrer d'autres modèles --Il y avait th: include dans la v2.x, mais il est obsolète dans la v3.x --Spécifiez le modèle à intégrer dans la valeur

  • La valeur spécifiée ici applique la même logique que lors de la résolution du fichier modèle à partir de la valeur de retour de la classe de contrôleur, donc faites-la correspondre.
  • Vous pouvez également utiliser une expression avec la valeur de th: insert (th: insert = "fragment / $ {name}")

Spécifiez le fragment à incorporer

embedded.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <span th:fragment="hoge">hoge</span>
        <span th:fragment="fuga">fuga</span>
    </body>
</html>

fragment.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Fragment</title>
    </head>
    <body>
        <h1>Hello Fragment</h1>
        <div id="foo"
             th:insert="fragment/embedded :: fuga"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

embedded.html


        <span th:fragment="hoge">hoge</span>
        <span th:fragment="fuga">fuga</span>

--Spécifiez le nom du fragment avec l'attribut th: fragment du côté de l'incorporation

fragment.html


        <div id="foo"
             th:insert="fragment/embedded :: fuga"></div>
  • En spécifiant [nom du modèle] :: [nom du fragment à incorporer] dans th: insert, vous ne pouvez incorporer que le fragment spécifié du modèle spécifié.

Remplacer complètement par th: remplacer

embedded.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <span id="hoge" th:fragment="hoge">
            HOGE
        </span>
    </body>
</html>

fragment.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Fragment</title>
    </head>
    <body>
        <h1>Hello Fragment</h1>
        <div id="foo"
             th:insert="fragment/embedded :: hoge"></div>
        <div id="bar"
             th:replace="fragment/embedded :: hoge"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

  • Dans le cas de th: insert, l'enfant de la balise avec le contenu ( th: fragment) de la balise de la cible d'intégration (ʻembedded.html) dans la balise du côté de la source d'intégration (fragment.html`). Element) est intégré
  • Dans le cas de th: replace, la balise du côté de la source d'intégration ( fragment.html) est remplacée par la balise elle-même (la balise elle-même avec th: fragment) de la cible d'intégration (ʻembedded.html`).

Passer des paramètres au fragment

embedded.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <body>
        <span th:fragment="hoge(p1, p2)">
            p1 = [[${p1}]], p2 = [[${p2}]]
        </span>
    </body>
</html>

fragment.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <title>Hello Fragment</title>
    </head>
    <body>
        <h1>Hello Fragment</h1>
        <div th:insert="fragment/embedded :: hoge('HOGE', 'FUGA')"></div>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

embedded.html


        <span th:fragment="hoge(p1, p2)">
            p1 = [[${p1}]], p2 = [[${p2}]]
        </span>
  • Après avoir déclaré le nom du fragment, vous pouvez déclarer les paramètres que le fragment reçoit sous la forme d'arguments de méthode.

fragment.html


        <div th:insert="fragment/embedded :: hoge('HOGE', 'FUGA')"></div>

--Le côté d'intégration peut passer un argument après le nom du fragment comme un appel de méthode

  • L'argument peut également être spécifié par son nom, tel que hoge (p1 = 'HOGE', p2 = 'FUGA')

Thymeleaf Layout Dialect Les fragments se présentaient sous la forme d'incorporer des parties communes dans des pages individuelles. Cette fois, au contraire, intégrez votre propre page dans la mise en page commune (en-tête et pied de page).

Ce processus lui-même ne peut pas être réalisé par la fonction standard seule, et il est nécessaire d'inclure une fonction d'extension appelée «thymeleaf-layout-dialect».

build.gradle


ext['thymeleaf.version'] = '3.0.7.RELEASE'
ext['thymeleaf-layout-dialect.version'] = '2.2.2'

Cette '' thymeleaf-layout-dialect.version '' est douloureuse.

Structure des dossiers


`-src/main/
  |-java/sample/thymeleaf/web/
  |  `-LayoutController.java
  |
  `-resources/templates/layout/
     |-layout.html
     `-content.html

LayoutController.java


package sample.thymeleaf.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LayoutController {
    
    @GetMapping("/layout")
    public String method() {
        return "layout/content";
    }
}

layout.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
        <meta charset="UTF-8" />
        <title>Layout File</title>
    </head>
    <body>
        <h1>Common Layout</h1>
        <section layout:fragment="content">
        </section>
    </body>
</html>

content.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">
    <body>
        <section layout:fragment="content">
            Content
        </section>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

LayoutController.java


    @GetMapping("/layout")
    public String method() {
        return "layout/content";
    }

--Spécifier comme modèle pour content.html

layout.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
        <meta charset="UTF-8" />
        <title>Layout File</title>
    </head>
    <body>
        <h1>Common Layout</h1>
        <section layout:fragment="content">
        </section>
    </body>
</html>
  • Déclarez xmlns: layout =" http://www.ultraq.net.nz/thymeleaf/layout " comme espace de noms --Définissez l'emplacement pour intégrer les informations de chaque page avec layout: fragment

content.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">
    <body>
        <section layout:fragment="content">
            Content
        </section>
    </body>
</html>

--Spécifiez le modèle dont la mise en page est définie par layout: decorate --Utilisez l'expression de fragment ajoutée dans la v3.x pour la valeur

  • L'expression de fragmentation est décrite au format ~ {}, et la position du modèle est spécifiée.
  • Le format de l'expression de fragment est presque le même que celui spécifié par th: insert.
  • Pour plus de détails, voir Document officiel
  • Au fait, cela fonctionne même si vous n'utilisez pas l'expression de fragment ~ {}, mais un message d'avertissement est envoyé à la console. --Selon le message, il ne sera plus utilisable à l'avenir

Titre du bâtiment

layout.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
    <head>
        <meta charset="UTF-8" />
        <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Layout</title>
    </head>
    <body>
        <h1>Common Layout</h1>
        <section layout:fragment="content">
        </section>
    </body>
</html>

content.html


<!doctype html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">
    <head>
        <title>Content</title>
    </head>
    <body>
        <section layout:fragment="content">
            Content
        </section>
    </body>
</html>

** Résultat d'exécution **

thymeleaf.jpg

La description

layout.html


        <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Layout</title>
  • Le contenu de <title> peut être une combinaison de ceux du fichier de mise en page et de ceux du fichier de contenu. --Définissez l'attribut layout: title-pattern sur <title> ʻ sur le côté du fichier de mise en page, et définissez la forme du combiné ʻ dans la valeur. --<code> $ LAYOUT_TITLE</code> fait référence à<code> <title></code> dans le fichier de mise en page, <code>$ CONTENT_TITLE</code> se réfère à<code><title></code>du côté du fichier de contenu.</li> </ul> <h4><strong><code>content.html</code></strong></h4> <pre><code class="language-html"> <head> <title>Content</title> </head> </code></pre> <ul> <li>Le côté du fichier de contenu déclare simplement <code><title></code> `normalement</li> </ul> <h4><strong><code>Titre HTML généré</code></strong></h4> <pre><code class="language-html"> <title>Layout - Content</title> </code></pre> <ul> <li>La valeur est une combinaison de «<title>» dans le fichier de mise en page et de «<title>» dans le fichier de contenu.</li> </ul> <h1>commentaire</h1> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <!-- standard html comment --> <!--/* --> <h1 th:text="'parser level comment'"></h1> <!-- */--> <!--/*/ <h1 th:text="'prototype comment'"></h1> /*/--> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/c0cc4e33-893f-4690-e693-70563966297f.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <p>--Il existe trois types de commentaires Thymeleaf</p> <h2>Commentaire HTML normal</h2> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!-- standard html comment --> </code></pre> <ul> <li>Ce sera un commentaire HTML normal --Il est sorti tel quel après le rendu, et il est traité comme un commentaire sur HTML.</li> </ul> <h2>Commentaires au niveau de l'analyseur</h2> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!--/* --> <h1 th:text="'parser level comment'"></h1> <!-- */--> </code></pre> <ul> <li>En commençant par <code><! - / *</code> Et en terminant par <code>* / -></code></li> <li>Ce commentaire est complètement supprimé au moment du rendu et n'existe plus sur HTML</li> <li>Vous pouvez également le mettre avec <code><! - / * -></code> Et <code><! - * / -></code>, donc il sera affiché lorsque vous l'ouvrirez dans un navigateur, mais il disparaîtra lorsque vous l'exécuterez sur le serveur. Peut être réalisé</li> </ul> <h2>Prototype uniquement commentaires</h2> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!--/*/ <h1 th:text="'prototype comment'"></h1> /*/--> </code></pre> <p>--La plage de <code><! - / * /</code> À <code>/ * / -></code> est applicable.</p> <ul> <li>Lorsqu'il est ouvert directement dans le navigateur, il est traité comme un simple commentaire HTML, mais le rendu Thymeleaf est ciblé. --Il est traité comme un commentaire en tant que prototype, mais il est utilisé lorsque vous souhaitez que Thymeleaf le traite lors de son exécution sur le serveur.</li> </ul> <h1>Ressource de message</h1> <h4><strong><code>Structure des dossiers</code></strong></h4> <pre><code class="language-text"> `-src/main/ |-java/sample/thymeleaf/ | |-web/ | | `-HelloController.java | `-Main.java | `-resources/ |-messages/ | `-Messages_ja.properties `-templates/ `-hello.html </code></pre> <h4><strong><code>Main.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ResourceBundleMessageSource; @SpringBootApplication public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages/Messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } } </code></pre> <h4><strong><code>Messages_ja.properties</code></strong></h4> <pre><code class="language-properties"> foo.message=Bonjour le monde bar.message=au revoir le monde </code></pre> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1 th:text="#{foo.message}"></h1> <h1 th:text="#{bar.message}"></h1> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/e710e099-a7f9-9ac0-bfc6-281be874c907.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>Main.java</code></strong></h4> <pre><code class="language-java"> import org.springframework.context.support.ResourceBundleMessageSource; ... @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages/Messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } </code></pre> <p>--Spécification du fichier de bundle de ressources géré par Spring</p> <ul> <li>Puisque le codage est réglé sur ʻUTF-8`, vous pouvez écrire le japonais tel qu'il est dans le fichier de message.</li> </ul> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <h1 th:text="#{foo.message}"></h1> <h1 th:text="#{bar.message}"></h1> </code></pre> <p>--Utilisez l'expression <code># {}</code> pour faire référence au message du modèle Thymeleaf. --Spécifiez la clé du message que vous souhaitez afficher à l'intérieur</p> <h2>Incorporer les paramètres dans le message</h2> <h4><strong><code>Messages_ja.properties</code></strong></h4> <pre><code class="language-properties"> foo.message=Bonjour{0} </code></pre> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1 th:text="#{foo.message('Sekai')}"></h1> <h1 th:text="#{foo.message('monde')}"></h1> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/e05dc968-f042-20fc-452b-5e672f412d85.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <h1 th:text="#{foo.message('Sekai')}"></h1> <h1 th:text="#{foo.message('monde')}"></h1> </code></pre> <p>--Si le message a un espace réservé, vous pouvez passer le paramètre comme un argument de méthode comme <code># {key name (parameter ...)}</code></p> <h1>Haricot de printemps</h1> <h4><strong><code>MySpringBean.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf; import org.springframework.stereotype.Component; @Component public class MySpringBean { public String hello() { return "Hello MySpringBean!!"; } } </code></pre> <h4><strong><code>hello.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Hello Thymeleaf</title> </head> <body> <h1 th:text="${@mySpringBean.hello()}"></h1> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/4914d432-4223-980a-9119-4c40dd46e744.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Puisque <code>$ {}</code> est évalué comme une expression SpEL, il est également possible de faire référence aux beans Spring. --Pour faire référence à un bean Spring, utilisez <code>@bean name</code></li> </ul> <h1>Lier des données de formulaire avec Spring MVC</h1> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; public class MyForm { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } </code></pre> <p>--Getter et Setter sont requis car la classe Form utilise par défaut l'accès aux propriétés.</p> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/form") public class FormController { @GetMapping public String init(Model model) { model.addAttribute(new MyForm()); return "form"; } @PostMapping public String submit(MyForm form) { System.out.println("form.value=" + form.getValue()); return "form"; } } </code></pre> <p>--Enregistrez l'objet de <code>MyForm</code> avec` Model.addAttribute () ʻau moment de l'affichage initial</p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <input type="text" th:field="*{value}" /> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/972095b9-16f3-75fd-798e-3640ded330c9.jpeg" alt="thymeleaf.jpg" /></p> <p>Entrez les caractères appropriés et cliquez sur le bouton Soumettre.</p> <h4><strong><code>Sortie de la console du serveur</code></strong></h4> <pre><code class="language-text"> form.value=test </code></pre> <p><strong>La description</strong></p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <form th:action="@{/form}" method="post" th:object="${myForm}"> <input type="text" th:field="*{value}" /> <input type="submit" value="Submit" /> </form> </code></pre> <ul> <li>Pour associer l'objet Form (<code>MyForm</code>) côté Java avec la balise<code> <form></code> de HTML, spécifiez l'objet Form enregistré dans le contrôleur avec la balise<code> th: object</code>.</li> <li>(Cela fonctionnait sans utiliser <code>th: object</code>, mais la documentation indiquait que c'était nécessaire ...) --Utilisez l'attribut <code>th: field</code> pour mapper chaque élément d'entrée aux propriétés du formulaire</li> </ul> <h2>Étiquette de la case à cocher</h2> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; public class MyForm { private boolean checked; public boolean isChecked() { return checked; } public void setChecked(boolean checked) { this.checked = checked; } } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <label th:for="${#ids.next('checked')}">checked</label> <input type="checkbox" th:field="*{checked}" /> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/085b5288-a438-e02e-255f-1ca5e17e2ee6.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Lors de l'utilisation de <code>th: field</code>, l'attribut ʻid<code>est automatiquement assigné par Thymeleaf. --Il devient difficile de spécifier</code>for`, surtout si vous créez plusieurs cases à cocher pendant la boucle.</li> <li>Pour prendre en charge cela, en spécifiant <code>$ {# ids.next ('[nom de la propriété que vous voulez associer]')}</code> avec <code>th: for</code>, vous pouvez définir la valeur d'attribut<code> for</code> sur la propriété cible. La valeur d'attribut ʻId<code>est définie --Utilisez</code>$ {# ids.prev ()}<code>si l'élément de la case à cocher précède</code><label>`</li> </ul> <h2>Boutons radio</h2> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import java.util.LinkedHashMap; import java.util.Map; public class MyForm { private String selectedValue = "piyo"; public Map<String, String> radioButtons() { Map<String, String> radioButtons = new LinkedHashMap<>(); radioButtons.put("hoge", "HOGE"); radioButtons.put("fuga", "FUGA"); radioButtons.put("piyo", "PIYO"); return radioButtons; } public String getSelectedValue() { return selectedValue; } public void setSelectedValue(String selectedValue) { this.selectedValue = selectedValue; } } </code></pre> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/form") public class FormController { @GetMapping public String init(Model model) { model.addAttribute(new MyForm()); return "form"; } @PostMapping public String submit(MyForm form) { System.out.println("form.selectedValue=" + form.getSelectedValue()); return "form"; } } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <div th:each="radioButton : *{radioButtons()}"> <label th:for="${#ids.next('selectedValue')}" th:text="${radioButton.value}"></label> <input type="radio" th:field="*{selectedValue}" th:value="${radioButton.key}" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/4ed25e52-6010-ad9f-7222-458f3a494010.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> private String selectedValue = "piyo"; public Map<String, String> radioButtons() { Map<String, String> radioButtons = new LinkedHashMap<>(); radioButtons.put("hoge", "HOGE"); radioButtons.put("fuga", "FUGA"); radioButtons.put("piyo", "PIYO"); return radioButtons; } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <div th:each="radioButton : *{radioButtons()}"> <label th:for="${#ids.next('selectedValue')}" th:text="${radioButton.value}"></label> <input type="radio" th:field="*{selectedValue}" th:value="${radioButton.key}" /> </div> </code></pre> <ul> <li>Pour mapper le bouton radio et le formulaire, préparez les deux --Informations pour créer des boutons radio (<code>raidoButtons ()</code>)</li> <li>Cette fois, j'ai utilisé <code>LinkedHashMap</code> pour le faire rapidement, mais en réalité, je pense que je vais préparer une classe de conteneur dédiée pour stocker les étiquettes et les valeurs et la mettre dans<code> List</code> etc. --Property pour stocker la valeur sélectionnée (<code>selectedValue</code>) --Créez des boutons radio en tournant le résultat de <code>radioButtons ()</code> avec <code>th: each</code></li> <li>Lors du mappage d'un bouton radio à un formulaire, il est obligatoire de spécifier non seulement <code>th: field</code> mais aussi<code> th: value</code>. --Parce que vous avez besoin de la valeur lorsque cet élément est sélectionné --Si vous souhaitez sélectionner la valeur initiale, définissez la valeur sélectionnée dans la propriété correspondante (<code>selectedValue =" piyo "</code>) --Si vous ne définissez pas de valeur, tous les éléments seront désélectionnés.</li> </ul> <h2>la liste déroulante</h2> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import java.util.LinkedHashMap; import java.util.Map; public class MyForm { private String selectedValue; public Map<String, String> options() { Map<String, String> radioButtons = new LinkedHashMap<>(); radioButtons.put("hoge", "HOGE"); radioButtons.put("fuga", "FUGA"); radioButtons.put("piyo", "PIYO"); return radioButtons; } public String getSelectedValue() { return selectedValue; } public void setSelectedValue(String selectedValue) { this.selectedValue = selectedValue; } } </code></pre> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/form") public class FormController { @GetMapping public String init(Model model) { model.addAttribute(new MyForm()); return "form"; } @PostMapping public String submit(MyForm form) { System.out.println("form.selectedValue=" + form.getSelectedValue()); return "form"; } } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <select th:field="*{selectedValue}"> <option th:each="option : *{options()}" th:value="${option.key}" th:text="${option.value}"> </option> </select> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/f3f980e5-5be6-db57-0057-8eb92a427a2a.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Pour générer dynamiquement une liste déroulante, bouclez <code><option></code> avec <code>th: each</code> --<code> th: field</code> est écrit dans la balise <code><select></code> --<code>th: value</code> doit être spécifié pour<code><option></code></li> </ul> <h2>Champ dynamique</h2> <p>Comment créer des éléments d'entrée qui peuvent dynamiquement ajouter / supprimer des lignes</p> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import java.util.ArrayList; import java.util.List; public class MyForm { private List<Row> rows = new ArrayList<>(); public void appendRow() { this.rows.add(new Row()); } public void removeRow(int index) { this.rows.remove(index); } public List<Row> getRows() { return rows; } public void setRows(List<Row> rows) { this.rows = rows; } public static class Row { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } } </code></pre> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @Controller @RequestMapping("/form") public class FormController { @GetMapping public String init(Model model) { model.addAttribute(new MyForm()); return "form"; } @PostMapping(params="appendRow") public String appendRow(MyForm form) { form.appendRow(); this.printRows(form); return "form"; } @PostMapping(params="removeIndex") public String submit(MyForm form, @RequestParam int removeIndex) { form.removeRow(removeIndex); this.printRows(form); return "form"; } private void printRows(MyForm form) { List<MyForm.Row> rows = form.getRows(); for (int i = 0; i < rows.size(); i++) { MyForm.Row row = rows.get(i); System.out.println("i=" + i + ", row.value=" + row.getValue()); } } } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <table border="1"> <tr> <th>No</th> <th>User input</th> <th>Remove Row</th> </tr> <tr th:each="row, loop : *{rows}"> <th th:text="${loop.count}"></th> <th> <input type="text" th:field="*{rows[__${loop.index}__].value}" /> </th> <th> <button type="submit" name="removeIndex" th:value="${loop.index}"> Remove </button> </th> </tr> </table> <input type="submit" name="appendRow" value="Append Row" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/5f982b10-b389-20f0-c8c3-3f51be5fe346.gif" alt="thymeleaf.gif" /></p> <p><strong>La description</strong></p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <tr th:each="row, loop : *{rows}"> <th th:text="${loop.count}"></th> <th> <input type="text" th:field="*{rows[__${loop.index}__].value}" /> </th> <th> <button type="submit" name="removeIndex" th:value="${loop.index}"> Remove </button> </th> </tr> </code></pre> <p>--Lors de l'association de champs qui augmentent ou diminuent dynamiquement, il faut en imaginer un peu pour spécifier <code>th: field</code>. --Simple <code>$ {row.value}</code> entraînera une erreur</p> <ul> <li>Chaque élément doit être accédé en indexant les <code>lignes</code></li> <li>De plus, la spécification d'index utilise le mécanisme de ** prétraitement **.</li> <li>Le pré-traitement est un mécanisme qui vous permet d'évaluer avant une expression normale, et il est décrit en l'enveloppant dans <code>__</code>. --<code>__ $ {loop.index} __</code> part --Cela permet à <code>* {rows [__ $ {loop.index} __] .value}</code> d'être évalué comme <code>* {rows [0] .value}</code> puis d'être évalué à l'intérieur de <code>* {}</code>. Devenez ainsi --Il semble fonctionner comme simplement <code>* {rows [loop.index] .value}</code>, mais malheureusement cela ne fonctionne pas.</li> <li>Cela est dû au fait que les expressions SpEL ne peuvent pas être spécifiées entre les parenthèses qui spécifient l'index de la liste.</li> </ul> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> @PostMapping(params="appendRow") public String appendRow(MyForm form) { form.appendRow(); this.printRows(form); return "form"; } @PostMapping(params="removeIndex") public String submit(MyForm form, @RequestParam int removeIndex) { form.removeRow(removeIndex); this.printRows(form); return "form"; } </code></pre> <p>--ʻAjouter une ligne<code>Pour identifier si l'utilisateur a cliqué sur le bouton ou sur le bouton</code>Supprimer<code>, spécifiez l'attribut</code> nom` pour le bouton et changez l'appel de méthode du contrôleur avec ou sans le paramètre. Est</p> <ul> <li>Les <code>paramètres</code> des annotations de mappage (<code> @ PostMapping</code>, <code>@ GetMapping</code>, etc.) peuvent être utilisés pour contrôler" exécuter s'il y a ce paramètre ".</li> </ul> <h1>Validation</h1> <p>Spring MVC fournit un mécanisme de vérification d'entrée utilisant la validation de bean. Thymeleaf fournit un mécanisme pour vérifier le résultat de cette erreur et afficher un message d'erreur.</p> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import javax.validation.constraints.Min; import javax.validation.constraints.Size; public class MyForm { @Size(min=3) private String text; @Min(100) private Integer number; public String getText() { return text; } public void setText(String text) { this.text = text; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } } </code></pre> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/form") public class FormController { @GetMapping public String init(Model model) { model.addAttribute(new MyForm()); return "form"; } @PostMapping public String submit(@Validated MyForm form, BindingResult result) { System.out.println("********************************************************"); System.out.println("form = " + form); System.out.println("result = " + result); System.out.println("********************************************************"); return "form"; } } </code></pre> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <div> <input type="text" th:field="*{text}" /> <ul th:each="error : ${#fields.errors('text')}"> <li th:text="${error}"></li> </ul> </div> <div> <input type="text" th:field="*{number}" /> <ul th:each="error : ${#fields.errors('number')}"> <li th:text="${error}"></li> </ul> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/5c69ea26-d22b-c96b-b2f7-bf5d1b7082fb.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> import javax.validation.constraints.Min; import javax.validation.constraints.Size; ... @Size(min=3) private String text; @Min(100) private Integer number; </code></pre> <p>--Annotez les champs du formulaire avec des annotations de validation de Bean et définissez le contenu du chèque</p> <ul> <li>Reportez-vous à <a href="http://qiita.com/opengl-8080/items/3926fbde5469c0b330c2">ici</a> pour savoir comment utiliser Bean Validation.</li> </ul> <h4><strong><code>FormController.java</code></strong></h4> <pre><code class="language-java"> import org.springframework.validation.annotation.Validated; ... @PostMapping public String submit(@Validated MyForm form, BindingResult result) { </code></pre> <ul> <li>La vérification d'entrée est activée en annotant l'objet de formulaire avec <code>@ Validated</code> dans l'argument de la méthode du contrôleur.</li> </ul> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <div> <input type="text" th:field="*{text}" /> <ul th:each="error : ${#fields.errors('text')}"> <li th:text="${error}"></li> </ul> </div> <div> <input type="text" th:field="*{number}" /> <ul th:each="error : ${#fields.errors('number')}"> <li th:text="${error}"></li> </ul> </div> </code></pre> <ul> <li>Les messages d'erreur générés par chaque propriété sont accessibles avec <code>$ {# fields.errors ('[property name]')}</code> --Les résultats sont répertoriés, vous pouvez donc obtenir chaque message d'erreur en boucle.</li> </ul> <h2>Vérifiez si l'élément est une erreur</h2> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <div> <input type="text" th:field="*{text}" /> <span th:if="${#fields.hasErrors('text')}">C'est une erreur!</span> </div> <div> <input type="text" th:field="*{number}" /> <span th:if="${#fields.hasErrors('number')}">C'est une erreur!</span> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/cef83323-8759-8f42-6293-876f5ded7dfb.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Vous pouvez vérifier s'il y a une erreur dans la propriété avec <code>$ {# fields.hasErrors ('[property name]')}</code></li> </ul> <h2>Spécifiez le style en cas d'erreur</h2> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <div> <input type="text" th:field="*{text}" class="always-assigned" th:errorclass="error-style" /> </div> <div> <input type="text" th:field="*{number}" class="always-assigned" th:errorclass="error-style" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/35a33496-3686-4b19-f79c-47bf2c69aa34.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <p>--Si vous spécifiez l'attribut <code>th: errorclass</code>, l'attribut de classe spécifié est ajouté uniquement lorsqu'une erreur se produit dans cette propriété. --Si vous voulez appliquer un style d'erreur, c'est plus simple et plus facile à comprendre que de faire quelque chose comme <code>$ {# fields.hasErrors ('text')? 'Error-style'}</code></p> <h2>Vérifiez s'il y a au moins une erreur</h2> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <h3 th:if="${#fields.hasAnyErrors()}">Il y a une erreur</h3> <div> <input type="text" th:field="*{text}" /> </div> <div> <input type="text" th:field="*{number}" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/ad90fe57-796f-432b-0100-0da477cf21ca.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <h3 th:if="${#fields.hasAnyErrors()}">Il y a une erreur</h3> </code></pre> <ul> <li>Vous pouvez vérifier s'il y a au moins une erreur avec <code># fields.hasAnyErrors ()</code></li> <li>Vous pouvez obtenir le même résultat avec <code># fields.hasErrors ('*')</code> ou <code># fields.hasErrors ('all')</code></li> </ul> <h2>Obtenez tous les messages d'erreur</h2> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <ul> <li th:each="error: ${#fields.allErrors()}"> [[${error}]] </li> </ul> <div> <input type="text" th:field="*{text}" /> </div> <div> <input type="text" th:field="*{number}" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/6f9fd659-105f-c40c-bc5b-5a12528a00ce.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Vous pouvez obtenir tous les messages d'erreur avec <code># fields.allErrors ()</code></li> <li>Cela fonctionne de la même manière si vous utilisez <code># fields.errors ('*')</code> ou <code># fields.errors ('all')</code>.</li> </ul> <h2>Erreur globale</h2> <p>Les erreurs qui ne sont pas liées à une propriété particulière sont appelées erreurs globales (probablement).</p> <p>Créez votre propre validation pour vérifier la corrélation et générer une erreur globale.</p> <h4><strong><code>MyValidation.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.validation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Constraint(validatedBy = MyValidator.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyValidation { String message() default "C'est une erreur!"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } </code></pre> <h4><strong><code>MyValidator.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.validation; import sample.thymeleaf.web.MyForm; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class MyValidator implements ConstraintValidator<MyValidation, MyForm> { @Override public void initialize(MyValidation constraintAnnotation) { System.out.println("MyValidator initialize"); } @Override public boolean isValid(MyForm value, ConstraintValidatorContext context) { System.out.println("MyValidator isValid"); if (value == null) { return true; } Integer number = value.getNumber(); if (number == null) { return true; } String text = value.getText(); if (number == 500) { return "500".equals(text); } return true; } } </code></pre> <p>--Varidata pour vérifier que <code>text</code> est également<code>" 500 "ʻif</code> nombre<code> est</code> 500`</p> <ul> <li>Pour savoir comment créer votre propre validateur, cliquez ici [http://qiita.com/opengl-8080/items/3926fbde5469c0b330c2#%E8%87%AA%E4%BD%9C%E3%81%AE%E3% 83% 90% E3% 83% AA% E3% 83% 87% E3% 83% BC% E3% 82% BF% E3% 81% A8% E5% 88% B6% E7% B4% 84% E3% 82% A2% E3% 83% 8E% E3% 83% 86% E3% 83% BC% E3% 82% B7% E3% 83% A7% E3% 83% B3% E3% 82% 92% E4% BD% 9C% Voir E6% 88% 90% E3% 81% 99% E3% 82% 8B)</li> </ul> <h4><strong><code>MyForm.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf.web; import sample.thymeleaf.validation.MyValidation; import javax.validation.constraints.Min; import javax.validation.constraints.Size; @MyValidation public class MyForm { @Size(min=3) private String text; @Min(100) private Integer number; ... } </code></pre> <p>--Annoter <code>MyForm</code> avec<code> @ MyValidation</code></p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <h3>[[${#fields.hasGlobalErrors()}]]</h3> <div> <input type="text" th:field="*{text}" /> </div> <div> <input type="text" th:field="*{number}" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p>Définissez «nombre» sur autre chose que «500» pour faire une erreur</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/51814ba2-c853-3bad-e2ce-094b53d98323.jpeg" alt="thymeleaf.jpg" /></p> <p>Remplacez «nombre» par «500» pour faire une erreur</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/3d294326-621a-d6b4-fb7e-d73d1fd02d62.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <h3>[[${#fields.hasGlobalErrors()}]]</h3> </code></pre> <ul> <li>Vous pouvez vérifier s'il y a des erreurs globales avec <code># fields.hasGlobalErrors ()</code> --C'est le même résultat avec <code># fields.hasErrors ('global')</code></li> </ul> <h3>Obtenir des messages d'erreur globaux</h3> <h4><strong><code>form.html</code></strong></h4> <pre><code class="language-html"> <!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <title>Form Sample</title> </head> <body> <form th:action="@{/form}" method="post" th:object="${myForm}"> <h3>[[${#fields.globalErrors()}]]</h3> <div> <input type="text" th:field="*{text}" /> </div> <div> <input type="text" th:field="*{number}" /> </div> <input type="submit" value="Submit" /> </form> </body> </html> </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/9d2d65b1-61e1-4266-6810-13f89fd05664.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>Vous pouvez obtenir tous les messages d'erreur globaux avec <code># fields.globalErrors ()</code></li> <li>Cela donne le même résultat avec <code># fields.errors ('global')</code></li> </ul> <h2>Modifier le message d'erreur</h2> <h4><strong><code>Main.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.support.ResourceBundleMessageSource; @SpringBootApplication public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.addBasenames("messages/Messages", "messages/validation-messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } } </code></pre> <h4><strong><code>MyWebConfig.java</code></strong></h4> <pre><code class="language-java"> package sample.thymeleaf; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Configuration; import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MyWebConfig extends WebMvcConfigurerAdapter { private MessageSource messageSource; public MyWebConfig(MessageSource messageSource) { this.messageSource = messageSource; } @Override public Validator getValidator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setValidationMessageSource(messageSource); return validator; } } </code></pre> <h4><strong><code>src/main/resources/messages/validation-messages_ja.properties</code></strong></h4> <pre><code class="language-properties"> javax.validation.constraints.Min.message = {value}Veuillez entrer ci-dessus </code></pre> <p>** Résultat d'exécution **</p> <p><img src="https://qiita-image-store.s3.amazonaws.com/0/28302/888cac70-0c40-1b53-3713-3ddafb14cd7d.jpeg" alt="thymeleaf.jpg" /></p> <p><strong>La description</strong></p> <ul> <li>En raison des spécifications de Bean Validation, vous pouvez écraser les messages par défaut en plaçant un fichier de propriétés avec <code>ValidationMessages</code> comme nom de base directement sous le chemin de classe. --Cependant, c'est un peu gênant car vous devez encoder le fichier de propriétés avec native2ascii.</li> <li>Si vous utilisez le mécanisme <code>MessageSource</code> de Spring, vous pouvez écrire des messages en UTF-8, ce qui est pratique.</li> </ul> <h4><strong><code>Main.java</code></strong></h4> <pre><code class="language-java"> @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.addBasenames("messages/Messages", "messages/validation-messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } </code></pre> <ul> <li>Ajout d'un fichier de message pour la validation de Bean avec ʻaddBasenames () `</li> </ul> <h4><strong><code>validation-messages_ja.properties</code></strong></h4> <pre><code class="language-properties"> javax.validation.constraints.Min.message = {value}Veuillez entrer ci-dessus </code></pre> <p>--Vérifiez le fichier de message par défaut pour savoir quelle est la clé --Hibernate Validator est inclus dans la dépendance, vous pouvez donc voir la liste des messages par défaut en regardant <code>ValidationMessages.properties</code> dans ce jar.</p> <h4><strong><code>ValidationMessages.properties</code></strong></h4> <pre><code class="language-properties"> javax.validation.constraints.AssertFalse.message = must be false javax.validation.constraints.AssertTrue.message = must be true javax.validation.constraints.DecimalMax.message = must be less than ${inclusive == true ? 'or equal to ' : ''}{value} javax.validation.constraints.DecimalMin.message = must be greater than ${inclusive == true ? 'or equal to ' : ''}{value} javax.validation.constraints.Digits.message = numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected) javax.validation.constraints.Future.message = must be in the future javax.validation.constraints.Max.message = must be less than or equal to {value} javax.validation.constraints.Min.message = must be greater than or equal to {value} javax.validation.constraints.NotNull.message = may not be null javax.validation.constraints.Null.message = must be null javax.validation.constraints.Past.message = must be in the past javax.validation.constraints.Pattern.message = must match "{regexp}" javax.validation.constraints.Size.message = size must be between {min} and {max} org.hibernate.validator.constraints.CreditCardNumber.message = invalid credit card number org.hibernate.validator.constraints.EAN.message = invalid {type} barcode org.hibernate.validator.constraints.Email.message = not a well-formed email address org.hibernate.validator.constraints.Length.message = length must be between {min} and {max} org.hibernate.validator.constraints.LuhnCheck.message = The check digit for ${validatedValue} is invalid, Luhn Modulo 10 checksum failed org.hibernate.validator.constraints.Mod10Check.message = The check digit for ${validatedValue} is invalid, Modulo 10 checksum failed org.hibernate.validator.constraints.Mod11Check.message = The check digit for ${validatedValue} is invalid, Modulo 11 checksum failed org.hibernate.validator.constraints.ModCheck.message = The check digit for ${validatedValue} is invalid, ${modType} checksum failed org.hibernate.validator.constraints.NotBlank.message = may not be empty org.hibernate.validator.constraints.NotEmpty.message = may not be empty org.hibernate.validator.constraints.ParametersScriptAssert.message = script expression "{script}" didn't evaluate to true org.hibernate.validator.constraints.Range.message = must be between {min} and {max} org.hibernate.validator.constraints.SafeHtml.message = may have unsafe html content org.hibernate.validator.constraints.ScriptAssert.message = script expression "{script}" didn't evaluate to true org.hibernate.validator.constraints.URL.message = must be a valid URL org.hibernate.validator.constraints.br.CNPJ.message = invalid Brazilian corporate taxpayer registry number (CNPJ) org.hibernate.validator.constraints.br.CPF.message = invalid Brazilian individual taxpayer registry number (CPF) org.hibernate.validator.constraints.br.TituloEleitoral.message = invalid Brazilian Voter ID card number </code></pre> <h1>référence</h1> <ul> <li><a href="http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.html">Tutorial: Using Thymeleaf (ja)</a></li> <li><a href="http://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html">Tutorial: Thymeleaf + Spring</a></li> <li><a href="http://qiita.com/kazuki43zoo/items/da64a68b9805e512cdc9">Méthode de configuration pour l'utilisation de la série Thymeleaf 3.0 avec Spring Boot 1.4 --Qiita</a></li> <li><a href="http://masatoshitada.hatenadiary.jp/entry/2016/08/10/132137">Utilisez Thymeleaf 3 avec Spring Boot 1.4 --Java EE Commencez! </a></li> <li><a href="https://github.com/spring-projects/spring-boot/issues/4393#issuecomment-233131972">Support Thymeleaf 3 · Issue #4393 · spring-projects/spring-boot</a></li> <li><a href="https://ultraq.github.io/thymeleaf-layout-dialect/">Introduction · Thymeleaf Layout Dialect</a></li> </ul> <!-- ENDDDDDDDDDDDDDDDDDDDDDDDDDDDDD --> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- ng_ads_new_ui --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6575041992772322" data-ad-slot="8191531813" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div style="margin-top: 30px;"> <div class="link-top" style="margin-top: 1px;"></div> <p> <font size="4">Recommended Posts</font> <!-- BEGIN LINK ************************* --> <div style="margin-top: 10px;"> <a href="/fr/eb3bf3b5301bae398cc2">Comment utiliser Thymeleaf avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/7d593272f4097fcc5690">Desserrer la vérification de la syntaxe de Thymeleaf dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/1153642f5a7eaab7fdf1">Définir le paramètre contextuel dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/6409669dc3f8b8071af4">Multi-projets Spring Boot 2 avec Gradle</a> </div> <div style="margin-top: 10px;"> <a href="/fr/764eed5328cf4e328161">[Java] Thymeleaf Basic (Spring Boot)</a> </div> <div style="margin-top: 10px;"> <a href="/fr/c26d99bb57888e42eaf1">Changements majeurs dans Spring Boot 1.5</a> </div> <div style="margin-top: 10px;"> <a href="/fr/c58085afa3358cca45fe">NoHttpResponseException dans Spring Boot + WireMock</a> </div> <div style="margin-top: 10px;"> <a href="/fr/142d4be2db9a6a540143">Spring Boot Hello World dans Eclipse</a> </div> <div style="margin-top: 10px;"> <a href="/fr/143783d9b5a604f14b97">Développement d'applications Spring Boot dans Eclipse</a> </div> <div style="margin-top: 10px;"> <a href="/fr/3f834119c756e5286730">Écrire du code de test avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/988ff69b678c7f00a2fe">Implémenter l'API REST avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/9e618f9f553938cf0fe4">Qu'est-ce que @Autowired dans Spring Boot?</a> </div> <div style="margin-top: 10px;"> <a href="/fr/af5298f58a505882f1e7">Implémenter l'application Spring Boot dans Gradle</a> </div> <div style="margin-top: 10px;"> <a href="/fr/3c4529a9d4643341da09">Lancer un (ancien) projet Spring Boot avec IntelliJ</a> </div> <div style="margin-top: 10px;"> <a href="/fr/4dffd2e4b6182d828341">Créer une image Spring Boot + Docker avec Gradle</a> </div> <div style="margin-top: 10px;"> <a href="/fr/4ec3733d44c9d2b618ee">Priorité d'accès aux fichiers statiques dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/57f7f9a2a3c4991b3cf8">Sortie du journal Spring Boot au format json</a> </div> <div style="margin-top: 10px;"> <a href="/fr/5cc060021ddf7cd108e4">Mémorandum de téléchargement de fichier local avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/77e3903ec0bb2aec8845">Créer un projet Java Spring Boot avec IntelliJ</a> </div> <div style="margin-top: 10px;"> <a href="/fr/8d7f71ebedeeb2526cee">[Entraine toi! ] Affichez Hello World avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/9b723d6210a26d512a9f">Utiliser la méthode de requête DynamoDB avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/c14302d266868c5b31fd">Implémenter CRUD avec Spring Boot + Thymeleaf + MySQL</a> </div> <div style="margin-top: 10px;"> <a href="/fr/ca68a3001bae19f92879">Implémenter la fonction de pagination avec Spring Boot + Thymeleaf</a> </div> <div style="margin-top: 10px;"> <a href="/fr/d937b7cf2cd5324cb992">Spring Boot + Thymeleaf Boot Strap Méthode d'installation mémo</a> </div> <div style="margin-top: 10px;"> <a href="/fr/e02cad0e81ad8ba9d73e">DI SessionScope Bean dans le filtre Spring Boot 2</a> </div> <div style="margin-top: 10px;"> <a href="/fr/f3afd40754f6ba587768">Modifier le délai d'expiration de la session dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/f847c23c3db37bd73ec3">Exécutez l'application WEB avec Spring Boot + Thymeleaf</a> </div> <div style="margin-top: 10px;"> <a href="/fr/76feb28f45a4ff9cc0ae">Défi Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/bbef095c87cab3720c70">Forme de botte de printemps</a> </div> <div style="margin-top: 10px;"> <a href="/fr/d2e456f08cafdaa74e90">gae + botte à ressort</a> </div> <div style="margin-top: 10px;"> <a href="/fr/0a2aca650721626055a3">Cookie SameSite dans Spring Boot (Spring Web MVC + Tomcat)</a> </div> <div style="margin-top: 10px;"> <a href="/fr/187f01d5639f8e3d0b50">Testez le contrôleur avec Mock MVC dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/18c24f5899c65c9487f7">Traitement asynchrone avec exécution régulière dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/322490b227e90d39aec1">Utilisez le mode de modèle de texte Thymeleaf de Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/39937cf39d2069758c83">Exécuter un projet Spring Boot avec VS Code</a> </div> <div style="margin-top: 10px;"> <a href="/fr/4ef1b71ad073eafc2135">Sortie des journaux de demande et de réponse avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/7bdfab8e974931afdac5">Utiliser le filtre de servlet avec Spring Boot [compatible Spring Boot 1.x, 2.x]</a> </div> <div style="margin-top: 10px;"> <a href="/fr/961b71a95daf3a2bce96">Conseils Java - Créez un projet Spring Boot avec Gradle</a> </div> <div style="margin-top: 10px;"> <a href="/fr/98f60c8064c369b32087">Créez une application CRUD avec Spring Boot 2 + Thymeleaf + MyBatis</a> </div> <div style="margin-top: 10px;"> <a href="/fr/aec763604f6496d32a0d">Remarques sur les annotations lors de l'écriture de tests pour Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/af71c0e8de0426dfb8f6">Créez votre propre utilitaire avec Thymeleaf avec Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/bc5c3b7796bb72fa049c">Comment se lier avec un fichier de propriétés dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/db039613637e1cf7bc88">Annotations utilisées dans les outils de gestion des tâches Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/f17fbdbca565c1ed8963">Afficher la tâche Gradle dans le projet Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/67a63c91a7db8717fc7d">Organisez les différences de comportement de @NotBlank, @NotEmpty et @NotNull avec Spring Boot + Thymeleaf</a> </div> <div style="margin-top: 10px;"> <a href="/fr/0268fa0db9820d639e56">Inject Logger au printemps</a> </div> <div style="margin-top: 10px;"> <a href="/fr/0767bde61bef6256f568">Spécifiez le codage des ressources statiques dans Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/13c7aae9019a28561f07">Fiche d'apprentissage SPRING BOOT 01</a> </div> <div style="margin-top: 10px;"> <a href="/fr/1d5e1fb5580a0c2b4fbc">Botte de printemps + Heroku Postgres</a> </div> <div style="margin-top: 10px;"> <a href="/fr/25e885d7d4fd05bbaf80">taglib printanier: notes de forme</a> </div> <div style="margin-top: 10px;"> <a href="/fr/26bd03b08fce1be6ff04">Exécution asynchrone des requêtes examinée dans Spring Boot 1.5.9</a> </div> <div style="margin-top: 10px;"> <a href="/fr/2c7dfd88e98827a800b5">Utilisation de th: include, th: replace, th: insert, th: fragment in Thymeleaf</a> </div> <div style="margin-top: 10px;"> <a href="/fr/30110cf4670d8db719cc">Si vous souhaitez séparer le traitement Spring Boot + Thymeleaf</a> </div> <div style="margin-top: 10px;"> <a href="/fr/4824d4a8c012f7ec53db">Mémo d'utilisation de Spring Security: coopération avec Spring MVC et Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/5b0283431f80643e7161">Comment créer un projet Spring Boot dans IntelliJ</a> </div> <div style="margin-top: 10px;"> <a href="/fr/5b86f162214f34d5e671">Première botte à ressort (DI)</a> </div> <div style="margin-top: 10px;"> <a href="/fr/5c2b2b7878ebcddf5017">Fiche d'apprentissage SPRING BOOT 02</a> </div> <div style="margin-top: 10px;"> <a href="/fr/5f7003bb78917dff6bb1">Aide-mémoire Spring Boot2</a> </div> <div style="margin-top: 10px;"> <a href="/fr/6b0f0fcfe681734e2617">Gestion des exceptions Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/75c54e747ed1bbbf71fa">Mappage du servlet Spring Boot</a> </div> <div style="margin-top: 10px;"> <a href="/fr/76a1b1c46f737cdbda5f">Environnement de développement-développement Spring Boot-</a> </div> <!-- END LINK ************************* --> </p> </div> </div> </div> <div class="footer text-center" style="margin-top: 40px;"> <!-- <p> Licensed under cc by-sa 3.0 with attribution required. </p> --> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.2/build/highlight.min.js"></script> <!-- ads --> <script data-ad-client="ca-pub-6575041992772322" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- end ads --> </body> </html>