[JAVA] Passer de JSP + JSTL à Thymeleaf

C'est le 7ème jour du Calendrier de l'Avent Asoview 2019.

Je suis Azuma, le rat brun de l'équipe de développement backend. Cette fois, je présenterai la table de correspondance lors du remplacement de la fonction JSP + JSTL utilisée depuis longtemps dans les applications Web Java par Thymeleaf.

Transfert de JSP + JSTL vers Thymeleaf

JSP était la méthode de facto pour créer des applications Web Java, mais maintenant que Spring Boot a adopté Thymeleaf, il y a des cas où la présentation est remplacée de JSP à Thymeleaf lorsque l'application existante est remplacée [^ 2].

Cette fois, je vais vous présenter comment remplacer la fonction utilisée dans JSTL de la bibliothèque de balises JSP + utilisée dans l'ancienne application Web Java par Thymeleaf, ainsi que la table de correspondance des fonctions.

[^ 2]: À l'origine, HTML était sorti sous forme de chaîne de caractères par un servlet, mais JSP permet d'écrire du code Java en considérant HTML comme un modèle. Cependant, la vitesse de fonctionnement de JSP n'est pas bonne, la lisibilité se détériore car la balise est superposée dans la balise et le code JSP est ajouté au HTML d'origine, donc si la conception ou la mise en page de l'écran est modifiée, le HTML et le JSP La maintenabilité n'était pas bonne, comme la correction de la différence.

Ce qui est ciblé cette fois

En plus des balises JSTL, nous présenterons également des éléments liés à l'utilisation des expressions JSP et EL.

Espace de nom Aperçu des fonctionnalités
c opération de base. Pour la sortie et le stockage temporaire des valeurs.
fmt Formatage du format de sortie
fn Fonction de traitement de sortie

N'est pas applicable

Espace de nom Aperçu des fonctionnalités Raison de l'exclusion
x opération xml(XPath et XSLT) Ne manipulez pas le XML ou les éléments dans Thymeleaf
sql Fonctionnement de la base de données Ne parcourez pas la base de données à partir de Thymeleaf[^1]

[^ 1]: Il existe une méthode pour faire référence à la source de données et à la sortie du bean de gestion Spring, en particulier la classe avec @ Service et @ Repository, en utilisant le plug-in Thymeleaf-Spring. Cependant, une gestion des transactions et une allocation de ressources appropriées doivent être effectuées, et le contenu mis en cache doit être renvoyé si nécessaire.

Core (espace de nom: c)

La balise principale est une balise fréquemment utilisée comme la sortie de valeur et le branchement conditionnel.

JSTL Thymeleaf Aperçu fonctionnel
<c:out> th:value、th:Fournit des attributs avec le même nom qui correspondent à la sortie du nom d'attribut en HTML, comme du texte. Sortie de la valeur transmise au modèle en HTML
<c:set> th:with Stocker la valeur dans la variable temporaire du modèle
<c:remove> (Aucun attribut correspondant) Supprimer les valeurs des variables temporaires et des attributs de servlet
<c:if> th:if Décrivez l'expression conditionnelle de la branche conditionnelle.
<c:choose> th:switch Subséquent<c:when>Ou e:Répertoriez les conditions dans l'élément case.
<c:when> th:case <c:choose>Et e:Élément enfant du commutateur
<c:forEach> th:each Boucle et sortie à plusieurs reprises. Définissez ici des variables temporaires telles que des éléments de boucle et des variables de règle
<c:forToken> #strings.arraySplit etc. Diviser la chaîne avec un délimiteur
<c:url> ${#uris.**} Générez une URL. Sert également de codage URL.
<c:import> th:insert, th:replace, th:include Capturer et afficher des ressources externes
<c:redirect> (Pas de fonction correspondante) Réorienter
<c:catch> (Pas de fonction correspondante) Gestion des exceptions qui se produisent lors de la sortie
<c:param> (Fourni en notation URL) Générer des paramètres de requête pour d'autres balises JSTL

Maintenant, je vais présenter chaque fonction et exemple d'utilisation tout en les comparant.

th: text: sortie vers le texte de la balise (= valeur de l'élément)

Sortie vers la valeur de l'élément

<div>message</div>

Pour afficher cela, comparons le cas du passage par nom: message et valeur: message.

thymeleaf JSP/JSTL
<div th:text="${message}">texte</div> <div><c:out value="${message}"/></div>

Thymeleaf renvoie les caractères de texte écrits dans la valeur d'élément du div comme contenu de th: text. Dans JSP, il est affiché même s'il n'est pas sorti via <c: out>, mais il passe toujours par <c: out> de JSTL pour nettoyer la valeur de sortie.

Sortie vers la valeur d'attribut

<input type="text" value="message" />

Pour afficher cela, la façon d'écrire lors du passage par nom: message, valeur: message,

thymeleaf JSP/JSTL
<input type="text" value="texte" th:value="${message}"/> <input type="text" value="<c:out value="${message}"/>" />

La valeur est réécrite comme ** Spécifiez le même nom d'attribut que l'attribut que vous souhaitez générer **, qui est également une fonctionnalité de Thymeleaf. En revanche, dans JSP / JSTL, c'est un peu difficile à lire car c'est une description qui renvoie la valeur à l'intérieur de la valeur d'attribut de la balise et l'enferme davantage dans la balise.

Concaténation de chaînes

La concaténation de chaînes est également possible dans les attributs de Thymeleaf. Lorsque vous écrivez directement la chaîne de caractères, placez-la entre guillemets simples.

<div th:text="'c'est,' + ${message} + 'est'">texte</div>

Le résultat en sortie est

<div>Ceci est un message</div>

th: with: Stocker la valeur dans une variable temporaire

Vous pouvez utiliser la valeur de sortie à plusieurs reprises lors de la sortie HTML, ou vous pouvez réaffecter la valeur pour modifier le contenu de sortie.

thymeleaf JSP/JSTL
<div th:with="another='${original}' +est">texte</div> <div><c:set value="${original}est" var="another"/></div>

Les variables temporaires définies dans les modèles Thymeleaf peuvent être référencées par l'élément qui définit la variable temporaire ainsi que ses éléments enfants. À Thymeleaf Nom: message, Valeur: Lorsqu'il est passé en tant que message

<div th:with="anotherMessage='c'est,' + ${message} + 'est'" th:text="${anotherMessage}">texte</div>

Le résultat en sortie est

<div>Ceci est un message</div>

Définir plusieurs variables temporaires

Si vous souhaitez définir plusieurs variables temporaires, connectez-les avec des virgules. Bien entendu, le traitement et le calcul des chaînes de caractères sont possibles même si plusieurs définitions sont décrites.

<div th:with="i=3, anotherMessage=${message} + 'est'">
	<span th:text="${anotherMessage}">texte</span>
	<span th:text="${i}">texte</span>
</div>

Le résultat en sortie est

<div>
	<span>Est un message</span>
	<span>3</span>
</div>

Définissez le même nom de variable

Que faire si je les stocke sous le même nom de variable?

<div th:with="message=${message} + 'est'">
	<span th:text="${message}">Texte 1</span>
</div>
<div th:text="${message}">Texte 2</div>

Dans ce cas, l'attribution de message ** est effectuée uniquement dans l'élément ** th: with.

<div>
	<span>Est un message</span>
</div>
<div>message</div>

La valeur temporairement définie dans th: with de Thymeleaf est ** valide uniquement pour cet élément et ses éléments enfants **. D'autre part, JSP + JSTL conserve le contenu stocké et le même contenu jusqu'à la sortie du texte 2. C'est une grande différence. Par conséquent, dans JSP, la valeur est supprimée avec <c: remove> et le traitement suivant se poursuit.

Lorsque vous traitez des variables temporaires dans Thymeleaf, utilisez-les en combinaison avec des attributs ultérieurs tels que le branchement conditionnel et le traitement en boucle tels que th: if et th: each.

Sortie de l'élément enfant et traitement de l'attribut thymeleaf suivant lorsque la condition th: if est remplie

Sortez le contenu de l'élément enfant ou exécutez la balise de l'élément enfant uniquement lorsque certaines conditions sont remplies. C'est la même chose pour JSP / JSTL et Thymeleaf, mais Thymeleaf génère les éléments qui définissent th: if. De plus, l'attribut thymeleaf (th: 〇〇) dans le même élément est exécuté.

thymeleaf JSP/JSTL
<div th:if="${original == 'message'}> <div><c:if test="${original == 'message'}"/></div>

Vous pouvez utiliser presque la même méthode et la même méthode pour écrire des expressions conditionnelles dans les valeurs d'attribut.

Système de base d'expression conditionnelle

À Thymeleaf Nom: message, Valeur: Lorsqu'il est passé en tant que message

<div th:if="${message == 'message'}">
	<span th:text="${message}">texte</span>
</div>

Ce résultat de sortie est

<div>
	<span>message</span>
</div>

Utiliser le code Java pour les expressions conditionnelles

Différents codes Java peuvent être écrits dans l'expression conditionnelle de th: if. Le plus utilisé est d'appeler une méthode de classe Java, et il est également possible de l'incorporer dans une expression conditionnelle ou de générer une valeur d'affichage uniquement.

<div th:if="${message.startsWith('Messe')}">
	<span th:text="${message}">texte</span>
</div>

Puisque le message variable était un message avec String, startsWith () est true, donc ce résultat de sortie est

<div>
	<span>message</span>
</div>

Ce sera.

Pour la sortie lorsque la condition n'est pas remplie, par exemple, ce qui suit détermine si la longueur de la chaîne de caractères du message variable est de 256 ou plus.

<div th:if="${message.length() >= 256}">
	<span th:text="${message}">texte</span>
</div>

Si la condition de cette instruction if n'est pas satisfaite, l'élément et les éléments enfants ne seront pas affichés dans leur intégralité. En d'autres termes, cet élément

n'est pas sorti.

Branche avec plusieurs conditions th: switch th: case

Le basculement vers la casse est le même que l'instruction de commutation Java, et si une condition n'est pas remplie, l'autre condition est vérifiée. Si même l'une des conditions n'est pas remplie, la condition est représentée par th: case =" * ".

<div th:switch="${message}">
	<span th:case="message" th:text="${message}"></span>
	<span th:case="*">Il n'y avait pas de message correspondant</span>
</div>

Si vous transmettez ce modèle Thymeleaf avec un nom: message et une valeur: message, il correspond au premier th: case, donc la sortie est la suivante.

<div>
	<span>message</span>
	
</div>

Les éléments qui ne sont pas générés seront des lignes vierges. Si la valeur de message est autre que message

<div>
	
	<span>Il n'y avait pas de message correspondant</span>
</div>

En plus des chaînes, th: case peut également être des valeurs numériques ou des valeurs énumérées (enum).

<div th:switch="${price}">
	<span th:case="100" th:text="${price}">prix</span>
	<span th:case="200" th:text="${price}">prix</span>
	<span th:case="300" th:text="${price}">prix</span>
	<span th:case="*" th:text="Il n'y a pas de prix applicable"></span>
</div>

Pour ce modèle, si la valeur du prix est de 200,

<div>

	<span>200</spam>


</div>

Est affiché, par exemple, si la valeur du prix est 150, la balise th: case à la fin est exécutée.

<div>



	<span>Il n'y a pas de prix applicable</spam>
</div>

Lors de l'utilisation de la valeur enum

Si les types d'énumération suivants sont définis

public enum Direction {
	North, South, East , West ;

	public String getValue() {
		return name();
	}
}

La méthode de vérification dans Thymeleaf peut être décrite comme suit.

<div th:switch="${direction.getValue()}">
	<span th:case="North" th:text="Nord"></span>
	<span th:case="East" th:text="est"></span>
	<span th:case="South" th:text="Sud"></span>
	<span th:case="West" th:text="Ouest"></span>
	<span th:case="*" th:text="N'est pas applicable"></span>
</div>

Si vous spécifiez le nom direction et la valeur: Direction.East pour ce modèle, le contenu de <span th: case =" East "th: text =" East "> </ span> est affiché.

Sortie répétée th: chaque

Il y a une différence dans la méthode de description entre JSTL et Thymeleaf dans la méthode de sortie répétée d'éléments tels que la sortie de table en utilisant «

» et la zone de liste en utilisant «
JSTL Thymeleaf Aperçu
<c:forEach> th:each Déclarer une sortie répétée

Pour afficher une zone de liste à l'aide de JSTL, entourez l'élément que vous souhaitez générer à plusieurs reprises avec <c: forEach>.

<select>
  <c:forEach var="result" items="${list}">
    <option value="<c:out value="${result.value}" />"><c:out value="${result.label}" /></option>
  </c:forEach>
</select>

Thymeleaf décrit th: each directement sur l'élément que vous souhaitez générer à plusieurs reprises. Il peut être décrit sans modifier la hiérarchie des balises.

<select>
  <option th:each="result : ${list}" th:value="${result.value}" th:inline="text">[[${result.label}]]</option>
</select>

Format (espace de nom: fmt)

Une fonction qui définit le format de sortie.

JSTL Thymeleaf Vue d'ensemble de la fonction de balise
<fmt:formatNumber> ${#numbers.formatInteger(..)} Format des nombres et des montants
<fmt:formatDate> ${#dates.format(..)} Format de date
<fmt:parseNumber> ※${#conversions.convert(object, targetClass)} Convertir des chaînes en nombres
<fmt:parseDate> ※${#conversions.convert(object, targetClass)} Convertir la chaîne en date
<fmt:setBundle> (Aucun) Définir le groupe de ressources
<fmt:bundle> (Aucun) Obtenir un ensemble de ressources
<fmt:message> #{messageId} Sortir le message spécifié de l'ensemble de ressources
<fmt:requestEncoding> (Aucun) Modifiez le codage des caractères de la demande.
<fmt:setLocale> (Aucun) Définissez les paramètres régionaux. Les paramètres régionaux après cette déclaration sont modifiés.
<fmt:setTimeZone> (Aucun) Réglez le fuseau horaire. Le fuseau horaire après cette déclaration est changé.
<fmt:timeZone> (Aucun) Renvoie le fuseau horaire.

En plus de définir le format de la valeur, fmt peut changer les paramètres régionaux et le fuseau horaire dans le même fichier JSP. Cela permet de modifier le type de variable lors de la sortie du modèle et de basculer la langue et le fichier de propriétés à afficher dans le message, mais il est préférable de basculer la JSP par locale que de basculer dans un fichier. Il est facile à maintenir et vous adopterez souvent une méthode qui change la disposition de l'écran pour chaque langue.

D'autre part, Thymeleaf propose une variété de conversions de format pour les chaînes, les montants et les dates. En voici quelques uns.

Thymeleaf Aperçu
${#dates.format(date, 'dd/MMM/yyyy HH:mm')} Sortie dans un format avec une date spécifiée
${#numbers.formatInteger(num,3)} Spécifiez le nombre minimum de chiffres d'affichage à afficher
${#numbers.formatPercent(num)} Notation en pourcentage
${#numbers.sequence(from,to)} Nombres consécutifs

Dans Thymeleaf, vous pouvez utiliser la fonction de conversion qui convertit le type d'une variable lors de la sortie du modèle pour la convertir en un autre type, mais le modèle génère uniquement la valeur de type et la convertit par inadvertance dans le modèle. L'écriture d'un processus qui fait cela réduira la lisibilité et devrait être évitée.

Fonction (espace de nom: fn)

Fonctions qui opèrent sur des chaînes. Dans Thymeleaf, si la variable est de type String, elle sera exécutée si vous écrivez la méthode telle quelle, mais toutes les fonctions fournies dans JSTL sont fournies dans la fonction # string.

JSTL Thymeleaf Vue d'ensemble de la fonction de balise
<fn:contains> ${#strings.contains(name,'ez')} Vrai si la chaîne spécifiée est incluse
<fn:containsIgnoreCase> ${#strings.containsIgnoreCase(name,'ez')} Vrai s'il contient la chaîne spécifiée, en ignorant la casse
<fn:indexOf> ${#strings.indexOf(name,frag)} Renvoie la position de la chaîne spécifiée
<fn:startsWith> ${#strings.startsWith(name,'Don')} Vrai si démarré à partir de la chaîne spécifiée
<fn:endsWith> ${#strings.endsWith(name,endingFragment)} Vrai si la chaîne spécifiée est à la fin
<fn:trim> ${#strings.trim(str)} Supprimer l'espace demi-largeur avant et après la chaîne de caractères
<fn:join> ${#strings.arrayJoin(namesArray,',')}Ou${#strings.listJoin(namesList,',')} Combiner des chaînes
<fn:replace> ${#strings.replace(name,'las','ler')} Remplacer la chaîne
<fn:split> ${#strings.arraySplit(namesStr,',')}Ou${#strings.listSplit(namesStr,',')} Fractionner par caractère spécifié
<fn:length> ${#strings.length(str)} Renvoie la longueur de la chaîne
<fn:substring> ${#strings.substring(name,3,5)} Couper avec la chaîne de caractères spécifiée
<fn:substringAfter> ${#strings.substringAfter(name,prefix)} Coupe la chaîne de caractères après la position spécifiée
<fn:substringBefore> ${#strings.substringBefore(name,suffix)} Couper la chaîne de caractères jusqu'à la position spécifiée
<fn:lowerCase> ${#strings.toLowerCase(name)} Faites-le plus bas
<fn:upperCase> ${#strings.toUpperCase(name)} Capitaliser
<fn:escapeXml> ${#strings.escapeXml(str)} HTML d'échappement
(Aucun) ${#strings.equals(first, second)} Vrai si les chaînes sont égales
(Aucun) ${#strings.equalsIgnoreCase(first, second)} Vrai si les chaînes sont égales, en ignorant la casse
(Aucun) ${#strings.randomAlphanumeric(count)} Renvoie une chaîne alphanumérique aléatoire avec le nombre de caractères spécifié

Objets implicites et portée de JSP

JSP a la portée d'attribut [^ 3] + la propre zone de JSP que possède le servlet, mais vous pouvez également y faire référence en spécifiant cette "portée" dans Thymeleaf.

Objet implicite de JSP Description en Thymeleaf
request #request
session #session
application #servletContext
page (Aucun)
config (Aucun)

Il existe une méthode d'acquisition distincte pour les paramètres Thymeleaf, référencée dans #execInfo.

[^ 3]: la portée définit la durée de vie lors du stockage des variables. Les attributs de requête, les attributs de session, les attributs d'application (ou les attributs de contexte de servlet) et JSP sont quatre autres attributs de contexte de page. Spring MVC a un attribut flash distinct.

Formule arithmétique / de vérification

Presque la même chose est disponible pour Thymeleaf.

JSP / EL Thymeleaf Aperçu du traitement
+ + somme
- - différence
* * produit
/ div / div Xu
% mod % mod reste
== eq == eq Équivalent
!= ne != ne Inégal
< lt < lt Côté gauche<côté droit
> gt > gt Côté gauche>côté droit
<= le <= le Côté gauche<=côté droit
>= ge >= ge Côté gauche>=côté droit
& and & ET logique(AND)
pipe or | Somme logique(OR)
! not ! not le déni(NOT)
empty (Aucun) Ciel

Gestion des exceptions

Dans JSP, s'il y a une erreur d'exécution lors de la sortie du modèle, vous pouvez déclarer le paramètre de transition vers la page d'erreur uniquement dans la directive JSP, ou essayer ~ catch dans le scriptlet (bien que ce ne soit pas recommandé) pour faire une exception. J'ai pu attraper et implémenter la gestion des exceptions.

La gestion des exceptions ne peut pas être implémentée dans Thymeleaf. La gestion des exceptions est implémentée dans la classe qui appelle le modèle Thymeleaf, car elle imprime uniquement la réponse pour l'erreur.

en conclusion

Comme mentionné ci-dessus, c'était un peu pressé, mais j'espère que cela aidera à remplacer l'implémentation de JSP + JSTL par Thymeleaf.

Recommended Posts

Passer de JSP + JSTL à Thymeleaf
Passer de slim3-gen à slim3-gen-jsr269
Passer d'Eclipse à VS Code
Réintroduction à JSTL
[Java] Comment passer de jdk ouvert à jdk oracle
Passer la classe Form du Controller à Symleaf avec Spring-Boot
Changements de Java 8 à Java 11
Somme de Java_1 à 100
Migrer de JUnit 4 vers JUnit 5
Introduction à Ratpack (9) --Thymeleaf
Balayez pour changer d'écran
De Java à Ruby !!
Passé d'iBATIS à MyBatis3
Migration de Cobol vers JAVA
Passer d'AWS à PaizaCloud
Nouvelles fonctionnalités de Java7 à Java8
Connectez-vous de Java à PostgreSQL
Conversion de ○ mois en ○ années ○ mois
Affichage d'erreur JSP à partir du servlet
Réécriture de l'applet à l'application
Passer de SQLite3 à PostgreSQL
De Java inefficace à Java efficace