Écrit par Thusitha T.
Introduction
Les moteurs de templates occupent une place clé dans la création de vues côté serveur, l’envoi d’emails personnalisés ou encore la génération de fichiers HTML à partir de données Java. Bien que des outils tels que Thymeleaf, FreeMarker ou Velocity soient populaires, un nouvel acteur a réussi à se démarquer grâce à sa performance et sa facilité d’utilisation : JTE (Java Template Engine).
Cet article vous propose une introduction à JTE, incluant ses principes opérationnels et ses bénéfices techniques, tout en fournissant un aperçu de son intégration au sein d’un projet Java modern.
Qu’est-ce que JTE ?
JTE (Java Template Engine) est un moteur de templates compilé, créé en 2020, qui vise à offrir une alternative plus rapide, sécurisée et typée aux moteurs de templates traditionnels utilisés dans les applications Java.
Contrairement à des solutions interprétées comme Thymeleaf ou FreeMarker, JTE compile les templates en classes Java au moment du build. Cela lui permet d’obtenir des performances proches de celles du code natif, tout en garantissant la détection d’erreurs à la compilation.
Objectif principal
JTE vise à fournir un moteur de templates modern pour Java, approprié aux contextes de haute performance (API, microservices, applications server-side rendering, etc.), tout en maintenant une simplicité d’apprentissage.
Les atouts majeurs
Haute Performance
L’un des atouts les plus marquants de JTE est dans sa rapidité d’exécution.
En effet, JTE supprime la phase d’interprétation. Les fichiers .jte sont transformés en classes Java lors de la compilation. Ainsi, les modèles sont donc directement exécutés comme du code Java optimisé par la JVM.
Des comparaisons indépendantes ont démontré que JTE peut être plus rapide que Thymeleaf ou FreeMarker dans différents scénarios.
Sécurité renforcée
En appliquant une échappement automatique du HTML et des autres formats (XML, JSON, etc.), JTE réduit drastiquement les risques d’injections XSS (Cross-Site Scripting).
De plus, comme les templates sont compilés, il n’y a aucune exécution dynamique de code, contrairement à d’autres moteurs plus permissifs.
Typage fort et vérification à la compilation
Etant donné que les templates JTE sont vérifiés à la compilation, si un champ ou une méthode n’existe plus dans un objet passé au template, l’erreur est détectée avant le déploiement, et non à l’exécution.
Intégration fluide
JTE ne nécessite pas de configuration complexe.
Un simple ajout de dépendance Maven ou Gradle suffit pour l’utiliser dans un projet Java.
Il s’intègre facilement avec des frameworks comme Spring Boot.
Installation
<dependency>
<groupId>gg.jte</groupId>
<artifactId>jte-spring-boot-starter-3</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>gg.jte</groupId>
<artifactId>jte</artifactId>
<version>3.2.1</version>
</dependency>
Les fichiers .jte placés dans src/main/resources/templates seront automatiquement détectés et rendus via les contrôleurs Spring (@Controller + ModelAndView).
Structure de base
src/
├─ main/
│ ├─ java/
│ ├─ resources/
│ │ └─ templates/
│ │ └─ hello.jte
Exemple de template hello.jte
@import java.time.LocalDateTime
<html>
<body>
<h1>Hello ${name}!</h1>
<p>Nous sommes le ${LocalDateTime.now()}.</p>
</body>
</html>
Contrôleur
import org.springframework.web.servlet.ModelAndView;
@GetMapping("/hello")
public ModelAndView hello() {
return new ModelAndView("hello", Map.of("name", "Jean"))
}
Classe Java générée du template
package jte;
import gg.jte.TemplateOutput;
import gg.jte.html.HtmlTemplateOutput;
import gg.jte.runtime.Template;
import java.time.LocalDateTime;
import java.util.Map;
public final class JtehelloGenerated implements Template {
@Override
public void render(Map<String, Object> params, TemplateOutput output) {
String name = (String) params.get("name");
output.writeContent("<html>\n <body>\n <h1>Hello ");
output.writeUserContent(name);
output.writeContent("!</h1>\n <p>Nous sommes le ");
output.writeUserContent(LocalDateTime.now());
output.writeContent(".</p>\n </body>\n</html>");
}
@Override
public static void render(Map<String, Object> params, HtmlTemplateOutput output) {
new JtehelloGenerated().render(params, output);
}
}
Explications
Le fichier .jte est transformé en une classe Java qui implémente l’interface gg.jte.runtime.Template et tout le contenu statique HTML est injecté via output.writeContent(...).
Les variables quant à elles (${name}, ${LocalDateTime.now()}) deviennent des appels Java typés et sûrs.
La méthode render est appelée par le moteur JTE lors de l’exécution.
Résultat affiché
<html>
<body>
<h1>Hello Jean!</h1>
<p>Nous sommes le 2025-10-23T14:35:10.123.</p>
</body>
</html>
Exemples d’utilisation de JTE
Affichage conditionnel
@if(isAdmin)
<p>Bienvenue, administrateur ${userName}.</p>
@else if(isGuest)
<p>Bienvenue, invité.</p>
@else
<p>Bienvenue, utilisateur.</p>
@end
Etant donné que le template est compilé en if / else Java, aucune erreur n’est possible à l’exécution.
Boucle for (foreach)
<ul>
@for(Product product : products)
<li>${product.getName()} — ${product.getPrice()} €</li>
@end
</ul>
Fragment réutilisable
Supposons que nous avons le fragment fragments/header.jte :
@param String title
<header>
<h1>${title}</h1>
</header>
En appelant ce dernier dans le template suivant :
@template.views.fragments.header(
title = "Accueil"
)
<main>
<p>Bienvenue sur notre site !</p>
</main>
Nous aurons le résultat suivant :
<header>
<h1>Accueil</h1>
</header>
<main>
<p>Bienvenue sur notre site !</p>
</main>
Limites et points de vigilance avec JTE
Même si JTE se distingue par ses performances et sa sécurité, il est important de connaitre ses limites avant de l’adopter dans un projet.
Recompilation après chaque modification
Vu que JTE travaille avec des templates compilés, lorsqu’on modifie un .jte, les modifications seront prises en compte seulement après recompilation.
Communauté encore jeune
Comparé à Thymeleaf ou FreeMarker, JTE dispose d’une communauté plus restreinte.
La documentation officielle est claire mais moins riche en exemples et moins d’intégrations tierces existent pour l’instant (tags Spring Security, intégrations JSP, etc.).
Moins d’écosystème autour des extensions
En misant sur la simplicité et la performance, JTE a un écosystème plus fermé que par exemple Thymeleaf qui propose des dialectes et des extensions personnalisables. Autrement dit, si le projet a besoin de tags ou de macros complexes, JTE sera moins adapté.
Extensions et plugins JTE encore limités
JTE propose plusieurs plugins officiels pour l’intégration dans les outils de build, mais ils restent moins matures que ceux des moteurs plus anciens :
| Plugin | Description | Limitation actuelle |
|---|---|---|
| jte-maven-plugin | Compile les templates .jte lors du mvn compile | Peu documenté, nécessite une configuration manuelle des chemins |
| jte-gradle-plugin | Compilation automatique dans Gradle | Incompatible avec certains environnements Gradle anciens (< 7) |
| jte-intellij-plugin | Coloration syntaxique et autocomplétion | Support partiel, pas encore complet sur les @include et @param |
| jte-spring-boot-starter | Intégration MVC avec Spring Boot | Fonctionne bien mais peu d’exemples complexes dans la doc |
Il n’y a exemple aucun plugin sur Eclipse ou VS Code permettant d’avoir la coloration syntaxique et l’autocomplétion.
Pas de Virtual DOM ni de rendu réactif
JTE est un moteur de rendu côté serveur pur :
il ne propose aucun Virtual DOM, ni mécanisme de réconciliation des changements de données comme le font des bibliothèques front-end (React, Vue, Svelte…).
Chaque rendu JTE recrée le HTML complet à partir du serveur, sans mise à jour partielle du DOM côté client.
Cela signifie que toute modification d’état nécessite un nouvel appel serveur et un rechargement complet de la vue.
Conclusion
JTE s’impose aujourd’hui comme une alternative aux moteurs historiques de templates Java.
Son approche compilée, son typage fort et sa sécurité intégrée en font un choix pertinent pour les développeurs cherchant à améliorer les performances et la fiabilité de leurs applications Java.
Autrement dit, il peut être l’idéal pour les applications où le contenu est statique au build (templates de mails, vues serveur, génération de rapports HTML). Par contre, s’il s’agit d’un projet avec des templates très dynamique, très intéractifs ou orientés utilisateur, un framework front moderne reste plus adapté.
Liens utiles
- Documentation officielle : jte: Java Template Engine – jte
- Repo GitHub : GitHub – casid/jte: Secure and speedy templates for Java and Kotlin.
- Intégration avec Spring Boot : jte Spring Boot 3 Starter – jte
À lire aussi
La Sobriété Numérique, de la quantification des émissions carbone des applications à la mise en œuvre des corrections
Introduction pratique au Q-learning avec Gymnasium Taxi-v3
Introduction à K6
