Apache FreeMarker est un moteur de modèle: une bibliothèque Java pour générer une sortie de texte (pages HTML, xml, fichiers de configuration, code source, etc.) Un modèle est envoyé à l'entrée, par exemple, html dans lequel il y a des expressions spéciales, des données correspondant à cette expression sont préparées, et Freemarker insère dynamiquement ces données et vous obtenez un document rempli dynamiquement.

Dans l'article FreeMarker
Botte de printemps
Macros
API REST
C'est-à-dire une expression simple sur freemarker est par exemple $ {name}, calculs, opérations de comparaison, conditions, boucles, listes, fonctions intégrées, macros et bien d'autres sont pris en charge dans l'expression. Exemple html avec l'expression $ {name} (template test.ftl):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>${name}!</title> </head> <body> <h2>Hello ${name}!</h2> </body> </html>
Si vous créez maintenant un modèle de données en java:
import freemarker.template.Configuration; import freemarker.template.Template; ...
puis nous obtenons un document html avec le nom rempli.
Si vous devez traiter la liste, la construction #list est utilisée, par exemple pour une liste html:
<ul> <#list father as item> <li>${item}</li> </#list> </ul>
En java, vous pouvez lister le modèle de données comme suit
Map<String, Object> root = new HashMap<>(); .... root.put("father", Arrays.asList("Alexander", "Petrov", 47));
Passons au printemps
La botte de printemps prend en charge Freemarker. Sur le site
SPRING INITIALIZR vous pouvez obtenir le fichier de projet pom.
fichier pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demoFreeMarker</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demoFreeMarker</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Classe DemoFreeMarkerApplication @SpringBootApplication public class DemoFreeMarkerApplication { public static void main(String[] args) { SpringApplication.run(DemoFreeMarkerApplication.class, args); } }
Spring a un composant de configuration préconfiguré pour freemarker. Pour un exemple d'application console, je prendrai l'interface Spring pour traiter la ligne de commande (CommandLineRunner) et préparer le modèle de données pour le modèle ftl suivant (hello_test.ftl):
Modèle Hello_test.ftl <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello ${name}!</title> </head> <body> <input type="text" placeholder="${name}"> <table> <#list persons as row> <tr> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </body> </html>
Code Java pour le modèle de données du modèle hello_test.ftl:
Classe CommandLine et modèle de données @Component public class CommandLine implements CommandLineRunner { @Autowired private Configuration configuration; public void run(String... args) { Map<String, Object> root = new HashMap<>();
Après le traitement, nous obtenons un document html:
Sortie html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Fremarker!</title> </head> <body> <input type="text" placeholder="Fremarker"> <table> <tr> <td>Alexander</td> <td>Petrov</td> <td>47</td> </tr> <tr> <td>Slava</td> <td>Petrov</td> <td>13</td> </tr> </table> </body>
Macros
Freemarker prend en charge les macros, il est très pratique et solide, et il est absolument nécessaire de l'utiliser.
Un exemple simple:
<#macro textInput id value=""> <input type="text" id="${id}" value="${value}"> </#macro>
Il s'agit d'une macro avec le nom textInput et les paramètres id (requis) et value (non requis, car il a une valeur par défaut). Vient ensuite son corps et l'utilisation des paramètres d'entrée. Dans le modèle, le fichier de macro est connecté comme suit:
<#import "ui.ftl" as ui/>
À partir du modèle, la macro est appelée comme ceci:
<@ui.textInput id="name" value="${name}"/>
Où ui est l'alias qui a été spécifié lors de la connexion, $ {name} est une variable dans le modèle, puis à travers l'alias nous nous référons au nom de macro textInput et spécifions ses paramètres, au moins obligatoires. Je vais préparer des macros simples pour l'entrée et le tableau html:
fichier macro ui.ftl <#-- textInput macro for html input --> <#macro textInput id placeholder="" value=""> <input type="text" id="${id}" placeholder="${placeholder}" value="${value}"> </#macro> <#-- table macro for html table --> <#macro table id rows> <table id="${id}"> <#list rows as row> <tr> <td>${row?index + 1}</td> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </#macro>
$ {row? index + 1} est la prise en charge intégrée de l'index d'un élément de liste; Si nous modifions maintenant le modèle principal précédent et remplaçons l'entrée et le tableau par des macros, nous obtenons le document suivant:
Modèle Hello.ftl <#import "ui.ftl" as ui/> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello ${name}!</title> </head> <body> <@ui.textInput id="name" placeholder="Enter name" value="${name}"/> <@ui.table id="table1" rows=persons/> </body> </html>
REPOS
Bien sûr, un tel modèle est pratique à utiliser dans une application Web. Je connecte la dépendance dans pom:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Ajouter un contrôleur REST:
DemoController.java @Controller public class DemoController { @Autowired private RepositoryService repositoryService; @GetMapping("/") public String index() { return "persons"; } @RequestMapping(value = "/search", method = RequestMethod.POST) public String hello(Model model, @RequestParam(defaultValue = "") String searchName) { List<List<String>> persons = repositoryService.getRepository(); List<List<String>> filterList = persons.stream() .filter(p -> p.get(0).contains(searchName)) .collect(Collectors.toList()); model.addAttribute("persons", filterList); model.addAttribute("lastSearch", searchName); return "persons"; } @RequestMapping(value = "/save", method = RequestMethod.POST) public String save(Model model, @ModelAttribute("person") Person person) { List<List<String>> persons = repositoryService.addPerson(person); model.addAttribute("persons", persons); return "persons"; } }
Référentiel de services pour les particuliers:
RepositoryService.java @Service public class RepositoryService { private static List<List<String>> repository = new ArrayList<>(); public List<List<String>> getRepository() { return repository; } public List<List<String>> addPerson(Person person) { repository.add(Arrays.asList(person.getFirstName(), person.getAge().toString())); return repository; } }
Classe de visage:
Person.java public class Person { public Person(String firstName, Integer age) { this.firstName = firstName; this.age = age; } private String firstName; private Integer age; public String getFirstName() { return firstName; } public Integer getAge() { return age; } }
Modèle de macro:
ui.ftl <#macro formInput id name label type="text" value=""> <label for="${id}">${label}</label> <input type="${type}" id="${id}" name="${name}" value="${value}"> </#macro> <#macro table id rows> <table id="${id}" border="1px" cellspacing="2" border="1" cellpadding="5"> <#list rows as row> <tr> <td>${row?index + 1}</td> <#list row as field> <td>${field}</td> </#list> </tr> </#list> </table> </#macro>
Le modèle principal:
persons.ftl <#import "ui.ftl" as ui/> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Person</title> <link href="style/my.css" rel="stylesheet"> </head> <body> <div> <fieldset> <legend> </legend> <form name="person" action="save" method="POST"> <@ui.formInput id="t1" name="firstName" label=""/> <br/> <@ui.formInput id="t2" name="age" label=""/> <br/> <input type="submit" value="Save" /> </form> </fieldset> </div> <div> <fieldset> <legend></legend> <form name="searchForm" action="search" method="POST"> <@ui.formInput id="t3" name="searchName" label=""/> <br/> <input type="submit" value="Search" /> </form> </fieldset> </div> <p><#if lastSearch??> : ${lastSearch}<#else></#if></p> <@ui.table id="table1" rows=persons![]/> </body> </html>
Structure du projet:

L'application traitera deux commandes «enregistrer» et «rechercher» du visage (voir contrôleur). Tous les travaux sur le traitement (cartographie) des paramètres d'entrée sont entrepris par Spring.
Quelques explications sur le modèle.
<#if lastSearch??> : ${lastSearch}<#else></#if>
il vérifie si le paramètre est défini, puis affiche la phrase "Rechercher: ..", sinon rien:
<@ui.table id="table1" rows=persons![]/>
ici aussi, on a vérifié que la liste des personnes était présente, sinon elle est vide. Ces vérifications sont importantes lorsque vous ouvrez la page pour la première fois, sinon vous devrez les initialiser dans le contrôleur index ().
Travail d'application

Matériaux:
→
Manuel Apache FreeMarker