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'
spring-boot-devtools
est un outil qui vous permet de refléter immédiatement les changements de code? Donc, ce n'est pas directement lié à l'utilisation de Thymeleaf, mais il est inclus car c'est pratiquespring-boot-starter-thymeleaf
est ajouté à la dépendance), le système ver 2.x sera adopté.thymeleaf.version '' et
thymeleaf-layout-dialect.version '' à la propriété étendue (ʻext`).'thymeleaf-layout-dialect.version'
spécifie la version de nz.net.ultraq.thymeleaf: thymeleaf-layout-dialect
respectivement.
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.
src / main / resources / templates / hello.html
sera utilisé comme fichier modèle.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>
xmlns: th =" http://www.thymeleaf.org "
** Résultat d'exécution **
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 **
La description
hello.html
<h1 th:text="'hello world'"></h1>
th: text =" [valeur à afficher] "
, l'élément texte de cette balise peut être affiché.[valeur à afficher]
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 **
La description
--Avec [[[valeur à afficher]]]
, vous pouvez afficher la valeur directement sur le modèle sans utiliser th: text
.
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 **
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 ()`.
<!--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>
<span th:text="'some text' + '!!'"></span>
+
<span th:text="|Hello ${message}|"></span>
$ {}
dans une chaîne littérale entre `|<span th:text="(30 * 20 + 10 / 5 - 1) % 3"></span>
--*
,/
,+
, '-', '%' peuvent être utilisés
<span th:text="true
and false
or true
and not true
or !false"></span>
ou ʻor
--Peut être refusé avec "pas" ou "!"<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)
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 **
** [Condition]? [Valeur]
**
false
** [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]
**
null
--S'il est différent de «null», [object] est évalué tel quel.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.
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.
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.
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 **
La description
publics
getXxx ()
peut être accédée en tant que propriété avec ʻobjectName.xxx (la méthode doit être
publique). --Les champs et propriétés peuvent également être référencés entre crochets, tels que ʻobjectName ['name']
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 **
La description
--Pour Map
, vous pouvez faire référence à la valeur avec map. Key
.
map ['key']
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 **
La description
--Pour accéder à List
et aux éléments d'un tableau, utilisez list [index]
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 **
La description
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 **
La description
@ {...}
peut être utilisée pour construire un chemin dans un format qui complète bien le chemin de contexte, etc.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 (/foo Devient 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.
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 **
La description
()
) à la fin du 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 **
La description
()
à la fin peuvent être utilisées dans le chemin entre {}
.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 dans
ServletContext --
param,
session, ʻapplication
peuvent être référencés comme`` Map --
param ['nom_paramètre'] `etc.
--httpServletRequest
est préfixé par#
, pas session
ou param
#
n'est pas attaché, sa valeur est recherchée à partir de la variable implicite # vars
.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 **
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.
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 **
La description
hello.html
<div th:with="message = 'Hello World!!'">
message = [[${message}]]
</div>
th: with
deviennent des variables valides uniquement dans les éléments enfants de cette balise et peuvent être référencées dans` $ {} ʻexpressions.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 **
La description
--Si vous utilisez th: if =" [condition] "
, il ne sera affiché que lorsque [condition] est ** une valeur évaluée à true **.
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 **
** 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 "
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?
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 **
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
, elle peut être traitée de manière itérative avec
th: each`.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 **
La description
--Lorsque Map
est traité de manière itérative, Map.Entry
est traité de manière itérative comme chaque élément.
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 **
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.
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 **
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
Nom de variable | sens |
---|---|
index |
Index de la boucle actuelle (0 Début) |
count |
Nombre de boucles actuel (1 Dé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 **
La description
hello.html
<th:block th:each="element : ${list}">
<h2>[[${element}]]</h2>
</th:block>
<th: block>
est complètement effacée après le renduth: if
, etc.) peut être écrit, il n'est donc pas nécessaire d'augmenter la balise <div>
juste pour écrire le traitement.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 **
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
th: insert
(th: insert = "fragment / $ {name}"
)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 **
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>
[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é.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 **
La description
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é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`).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 **
La description
embedded.html
<span th:fragment="hoge(p1, p2)">
p1 = [[${p1}]], p2 = [[${p2}]]
</span>
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
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 **
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>
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
~ {}
, et la position du modèle est spécifiée.th: insert
.~ {}
, mais un message d'avertissement est envoyé à la console.
--Selon le message, il ne sera plus utilisable à l'avenirlayout.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 **
La description
layout.html
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Layout</title>
<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é
$ LAYOUT_TITLE
fait référence à <title>
dans le fichier de mise en page, $ CONTENT_TITLE
se réfère à<title>
du côté du fichier de contenu.content.html
<head>
<title>Content</title>
</head>
<title>
`normalementTitre HTML généré
<title>Layout - Content</title>
hello.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>
** Résultat d'exécution **
La description
--Il existe trois types de commentaires Thymeleaf
hello.html
<!-- standard html comment -->
hello.html
<!--/* -->
<h1 th:text="'parser level comment'"></h1>
<!-- */-->
<! - / *
Et en terminant par * / ->
<! - / * ->
Et <! - * / ->
, 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éhello.html
<!--/*/
<h1 th:text="'prototype comment'"></h1>
/*/-->
--La plage de <! - / * /
À / * / ->
est applicable.
Structure des dossiers
`-src/main/
|-java/sample/thymeleaf/
| |-web/
| | `-HelloController.java
| `-Main.java
|
`-resources/
|-messages/
| `-Messages_ja.properties
`-templates/
`-hello.html
Main.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;
}
}
Messages_ja.properties
foo.message=Bonjour le monde
bar.message=au revoir le monde
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="#{foo.message}"></h1>
<h1 th:text="#{bar.message}"></h1>
</body>
</html>
** Résultat d'exécution **
La description
Main.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;
}
--Spécification du fichier de bundle de ressources géré par Spring
hello.html
<h1 th:text="#{foo.message}"></h1>
<h1 th:text="#{bar.message}"></h1>
--Utilisez l'expression # {}
pour faire référence au message du modèle Thymeleaf.
--Spécifiez la clé du message que vous souhaitez afficher à l'intérieur
Messages_ja.properties
foo.message=Bonjour{0}
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="#{foo.message('Sekai')}"></h1>
<h1 th:text="#{foo.message('monde')}"></h1>
</body>
</html>
** Résultat d'exécution **
La description
hello.html
<h1 th:text="#{foo.message('Sekai')}"></h1>
<h1 th:text="#{foo.message('monde')}"></h1>
--Si le message a un espace réservé, vous pouvez passer le paramètre comme un argument de méthode comme # {key name (parameter ...)}
MySpringBean.java
package sample.thymeleaf;
import org.springframework.stereotype.Component;
@Component
public class MySpringBean {
public String hello() {
return "Hello MySpringBean!!";
}
}
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="${@mySpringBean.hello()}"></h1>
</body>
</html>
** Résultat d'exécution **
La description
$ {}
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 @bean name
MyForm.java
package sample.thymeleaf.web;
public class MyForm {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
--Getter et Setter sont requis car la classe Form utilise par défaut l'accès aux propriétés.
FormController.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";
}
}
--Enregistrez l'objet de MyForm
avec` Model.addAttribute () ʻau moment de l'affichage initial
form.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>
** Résultat d'exécution **
Entrez les caractères appropriés et cliquez sur le bouton Soumettre.
Sortie de la console du serveur
form.value=test
La description
form.html
<form th:action="@{/form}" method="post" th:object="${myForm}">
<input type="text" th:field="*{value}" />
<input type="submit" value="Submit" />
</form>
MyForm
) côté Java avec la balise <form>
de HTML, spécifiez l'objet Form enregistré dans le contrôleur avec la balise th: object
.th: object
, mais la documentation indiquait que c'était nécessaire ...)
--Utilisez l'attribut th: field
pour mapper chaque élément d'entrée aux propriétés du formulaireMyForm.java
package sample.thymeleaf.web;
public class MyForm {
private boolean checked;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
form.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>
** Résultat d'exécution **
La description
th: field
, l'attribut ʻidest automatiquement assigné par Thymeleaf. --Il devient difficile de spécifier
for`, surtout si vous créez plusieurs cases à cocher pendant la boucle.$ {# ids.next ('[nom de la propriété que vous voulez associer]')}
avec th: for
, vous pouvez définir la valeur d'attribut for
sur la propriété cible. La valeur d'attribut ʻIdest définie --Utilisez
$ {# ids.prev ()}si l'élément de la case à cocher précède
MyForm.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;
}
}
FormController.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";
}
}
form.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>
** Résultat d'exécution **
La description
MyForm.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;
}
form.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>
raidoButtons ()
)LinkedHashMap
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 List
etc.
--Property pour stocker la valeur sélectionnée (selectedValue
)
--Créez des boutons radio en tournant le résultat de radioButtons ()
avec th: each
th: field
mais aussi th: value
.
--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 (selectedValue =" piyo "
)
--Si vous ne définissez pas de valeur, tous les éléments seront désélectionnés.MyForm.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;
}
}
FormController.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";
}
}
form.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>
** Résultat d'exécution **
La description
<option>
avec th: each
-- th: field
est écrit dans la balise <select>
--th: value
doit être spécifié pour<option>
Comment créer des éléments d'entrée qui peuvent dynamiquement ajouter / supprimer des lignes
MyForm.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;
}
}
}
FormController.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());
}
}
}
form.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>
** Résultat d'exécution **
La description
form.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>
--Lors de l'association de champs qui augmentent ou diminuent dynamiquement, il faut en imaginer un peu pour spécifier th: field
.
--Simple $ {row.value}
entraînera une erreur
lignes
__
.
--__ $ {loop.index} __
part
--Cela permet à * {rows [__ $ {loop.index} __] .value}
d'être évalué comme * {rows [0] .value}
puis d'être évalué à l'intérieur de * {}
. Devenez ainsi
--Il semble fonctionner comme simplement * {rows [loop.index] .value}
, mais malheureusement cela ne fonctionne pas.FormController.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";
}
--ʻAjouter une lignePour identifier si l'utilisateur a cliqué sur le bouton ou sur le bouton
Supprimer, spécifiez l'attribut
nom` pour le bouton et changez l'appel de méthode du contrôleur avec ou sans le paramètre. Est
paramètres
des annotations de mappage ( @ PostMapping
, @ GetMapping
, etc.) peuvent être utilisés pour contrôler" exécuter s'il y a ce paramètre ".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.
MyForm.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;
}
}
FormController.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";
}
}
form.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>
** Résultat d'exécution **
La description
MyForm.java
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
...
@Size(min=3)
private String text;
@Min(100)
private Integer number;
--Annotez les champs du formulaire avec des annotations de validation de Bean et définissez le contenu du chèque
FormController.java
import org.springframework.validation.annotation.Validated;
...
@PostMapping
public String submit(@Validated MyForm form, BindingResult result) {
@ Validated
dans l'argument de la méthode du contrôleur.form.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>
$ {# fields.errors ('[property name]')}
--Les résultats sont répertoriés, vous pouvez donc obtenir chaque message d'erreur en boucle.form.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>
** Résultat d'exécution **
La description
$ {# fields.hasErrors ('[property name]')}
form.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>
** Résultat d'exécution **
La description
--Si vous spécifiez l'attribut th: errorclass
, 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 $ {# fields.hasErrors ('text')? 'Error-style'}
form.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>
** Résultat d'exécution **
La description
form.html
<h3 th:if="${#fields.hasAnyErrors()}">Il y a une erreur</h3>
# fields.hasAnyErrors ()
# fields.hasErrors ('*')
ou # fields.hasErrors ('all')
form.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>
** Résultat d'exécution **
La description
# fields.allErrors ()
# fields.errors ('*')
ou # fields.errors ('all')
.Les erreurs qui ne sont pas liées à une propriété particulière sont appelées erreurs globales (probablement).
Créez votre propre validation pour vérifier la corrélation et générer une erreur globale.
MyValidation.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 {};
}
MyValidator.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;
}
}
--Varidata pour vérifier que text
est également" 500 "ʻif
nombre est
500`
MyForm.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;
...
}
--Annoter MyForm
avec @ MyValidation
form.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>
** Résultat d'exécution **
Définissez «nombre» sur autre chose que «500» pour faire une erreur
Remplacez «nombre» par «500» pour faire une erreur
La description
form.html
<h3>[[${#fields.hasGlobalErrors()}]]</h3>
# fields.hasGlobalErrors ()
--C'est le même résultat avec # fields.hasErrors ('global')
form.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>
** Résultat d'exécution **
La description
# fields.globalErrors ()
# fields.errors ('global')
Main.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;
}
}
MyWebConfig.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;
}
}
src/main/resources/messages/validation-messages_ja.properties
javax.validation.constraints.Min.message = {value}Veuillez entrer ci-dessus
** Résultat d'exécution **
La description
ValidationMessages
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.MessageSource
de Spring, vous pouvez écrire des messages en UTF-8, ce qui est pratique.Main.java
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.addBasenames("messages/Messages", "messages/validation-messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
validation-messages_ja.properties
javax.validation.constraints.Min.message = {value}Veuillez entrer ci-dessus
--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 ValidationMessages.properties
dans ce jar.
ValidationMessages.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
Recommended Posts