1. Présentation
Freemarker est un moteur de modèle, un outil général pour générer une sortie de texte basée sur des modèles. Il est écrit en java pur. Freemarker est conçu pour générer des pages Web HTML, en particulier les applications basées sur le modèle MVC. Bien que Freemarker ait des capacités de programmation, il prépare généralement les données à afficher par les programmes Java et génère les pages par freemarker et affiche les données préparées via le modèle (comme indiqué ci-dessous).
Freemarker n'est pas un cadre d'application Web, mais convient en tant que composant du framework d'application Web. Freemarker n'est pas lié aux conteneurs car il ne connaît pas le HTTP ou les servlets; Freemarker peut également être appliqué aux environnements d'application non Web, Freemarker est plus approprié en tant que composant de vue des frameworks Model2 (tels que les jambes de force), et vous pouvez également utiliser la bibliothèque de balises JSP dans les modèles. De plus, Freemarker est gratuit.
2. Conditions de préparation des freemarker
Freemarker.2.3.16.jar, l'adresse de téléchargement ne sera pas publiée ici ... (ce package JAR est en fait en Struts2)
3. Le principe du freemarker générant des pages statiques
Freemarker génère une page statique. Tout d'abord, vous devez utiliser la page de modèle que vous définissez vous-même. Cette page de modèle peut être le HTML le plus ordinaire, ou il peut être une expression de valeur imbriquée, une étiquette ou une balise personnalisée, etc. dans le freemarker. Ensuite, la page de modèle est lue en arrière-plan, analysez les balises pour terminer l'opération correspondante, puis transmettez les paramètres dans la paire de valeurs clés pour remplacer l'expression de la valeur dans le modèle. Après cela, une nouvelle page HTML peut être générée en fonction du chemin configuré pour atteindre l'objectif de l'accès statique.
4. Étiquettes fournies par Freemarker
Freemarker fournit de nombreuses balises utiles et couramment utilisées. Les balises Freemarker sont nommées <# TAG NAME> comme ceci. $ {valeur} représente le contenu du nom de la variable de sortie, comme suit:
1. Liste: cette balise est principalement une collection de liste passée du côté serveur à travers itérativement, telles que:
<#List namelist comme noms> $ {noms} </ # list>Le nom est une variable de boucle prise lorsque la boucle de liste. Lorsque Freemarker analyse la balise de liste, elle équivaut à:
for (String Names: nameList) {System.out.println (noms); }2. Si: cette balise est principalement utilisée pour le jugement, comme:
<#if (noms == "Chen Jingchou")> Ses armes sont: quinze ~~ </ # if>
Il s'agit d'une étiquette de jugement conditionnelle. Il convient de noter que l'équation conditionnelle doit être enfermée entre parenthèses, ce qui équivaut à:
if (names.equals ("Chen Jingchou")) {System.out.println ("Ses armes sont: quinze ~~"); }
3. Inclure: cette balise est utilisée pour importer des fichiers.
<#include "include.html" />
Cette balise d'importation est très utile, en particulier pour la réutilisation des pages.
De plus, vous pouvez utiliser $ {} pour obtenir la valeur dans un fichier statique. La méthode de valeur est la même que l'expression EL, ce qui est très pratique.
Voici un exemple (static.html):
<! Doctype html public "- // w3c // dtd html 4.01 transitional // en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <read> <metml <Title> Insérer le titre ici </ title> </ head> <body> Description: $ {description} <br/> Taille de la collection: $ {namelist? Taille} <br/> COLLECTION ITERATIVE: <br/> <#List namelist comme nom (names=="Chen Jingchou")> His weapons are: fifteen~~ <#elseif (names=="Yuwentuo")> <#-Note that there is no return here but at the end--> His weapons are: Xuanyuan Sword~・ <#else> Her trick is: Gu Poison~~ </#if> <br/> </#list> Iterative map collection: <br/> <#list armemap? Keys as Key> key ---> $ {key} <br/> value -----> $ {armeNMap [key]! ("null")} <# - Fremarker ne prend pas en charge null, peut être utilisé! au lieu d'une valeur vide. En fait, vous pouvez également donner une valeur par défaut ----- $ {armesmap [key]? Default ("null")} Vous pouvez également déterminer s'il est null avant la sortie <#if armemap [key] ??Code réel:
package com.chenghui.test; Importer java.io.file; Importer java.io.fileOutputStream; Importer java.io.ioException; import java.io.outputStreamWriter; Importer java.io.writer; import java.util.arraylist; import java.util.hashmap; Importer java.util.list; importation java.util.map; Importer Freemarker.Template.configuration; Importer Freemarker.Template.DefaultObjectWrapper; Importer Freemarker.Template.Template; Importer Freemarker.Template.TemplateException; classe publique CreateHtml {public static void main (String [] args) {try {// Créer une configuration d'objet de configuration appropriée Configuration = new Configuration (); configuration.setDirectoryFortEmplateLoading (nouveau fichier ("d: // project // webProject // webContent // web-inf // modèle")); configuration.setObjectWrapper (new defaultObjectWrapper ()); configuration.setDefaultEncoding ("UTF-8"); // Cela doit être défini, sinon il sera brouillé dans la page générée // Obtenez ou créera un modèle. Modèle template = configuration.getTemplate ("static.html"); Map <string, object> parAmmap = new HashMap <String, object> (); Parammap.put ("Description", "J'apprends à utiliser Freemarker pour générer des fichiers statiques!"); List <string> nameList = new ArrayList <string> (); namelist.add ("Chen Jingchou"); namelist.add ("yuer"); namelist.add ("yuwentuo"); Parammap.put ("Namelist", Namelist); Map <string, objet> armeNMap = new HashMap <String, objet> (); armemap.put ("First", "Xuanyuan Sword"); armemap.put ("deuxième", "Kongtong Seal"); armemap.put ("Third", "Nuwa Stone"); armemap.put ("quatrième", "Shennong Ding"); armemap.put ("cinquième", "Fuxi Qin"); armemap.put ("Sixth", "Kunlun Mirror"); armemap.put ("septième", null); Parammap.put ("armemap", armemap); Écrivain écrivain = new outputStreamWriter (new FileOutputStream ("Success.html"), "UTF-8"); Template.Process (Parammap, écrivain); System.out.println ("Félicitations, la génération a réussi ~~"); } catch (ioException e) {e.printStackTrace (); } catch (templateException e) {e.printStackTrace (); }}}
Cela peut essentiellement être considéré comme une génération simple et simple, mais il est encore loin d'être utilisé dans la pratique, car les étiquettes données par Freemarker ne peuvent pas du tout répondre à nos besoins. Pour le moment, des balises personnalisées sont nécessaires pour répondre à nos besoins. .
5. Tags personnalisés Freemarker
Les balises personnalisées Freemarker sont d'écrire les balises par vous-même, puis de les analyser par vous-même. Ils contrôlent complètement l'entrée et la sortie des balises par elles-mêmes, ce qui offre grandement aux programmeurs avec beaucoup de place pour jouer.
Basé sur les étapes:
Dans le passé, lors de l'écriture de balises, vous devez ajouter # après <, mais pour reconnaître les balises personnalisées, vous devez ajouter @ après, puis vous pouvez définir certains paramètres plus tard. Lorsque le programme exécute Template.Process (Parammap, Out);, il analysera toutes les balises Freemarker sur toute la page.
La personnalisation de la balise nécessite la personnalisation d'une classe, puis la mise en œuvre de TemplateDirectiveModel, la réécriture de la méthode d'exécution, la réalisation de l'acquisition de paramètres, faites quelque chose en fonction des paramètres, etc.
Pour lier les balises personnalisées aux classes d'analyse, vous devez mettre une instance de la classe d'analyse dans Parammap, et la clé stockée est la même que la balise personnalisée. .
Remarque: Dans la balise personnalisée, s'il n'y a rien dans la balise, la balise de démarrage et la balise de fin ne doivent pas être la même ligne, sinon une erreur sera signalée.
freemarker.log.jdk14loggerfactory $ jdk14logger erreur
J'ai été dupe, et c'est un bug de Freemarker.
Voici un exemple de statique.html:
<! Doctype html public "- // w3c // dtd html 4.01 transitional // en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <read> <metml <Title> Insérez le titre ici </ title> </ head> <body> <# - Variables personnalisées -> <#assign num = 'hehe' /// $ {num} <br/> tags personnalisés <@content name = "CHENGHUI" Age = "120"> $ {output} $ {annex} </ @ contenu> </ody> </htm>
Voici la classe d'analyse du modèle statique.html ci-dessus:
package com.chenghui.test; Importer Static Freemarker.Template.ObjectWrapper.default_wrapper; Importer java.io.ioException; Importer java.io.writer; importation java.util.map; importer freemarker.core.environment; Importer FreeMarker.Template.TemplateDirectiveChody; Importer Freemarker.Template.TemplateDireCiveModel; Importer Freemarker.Template.TemplateException; Importer Freemarker.Template.TemplateModel; Importer Freemarker.Template.TemplateModeLexception; Importer Freemarker.Template.TemplaTenumberModel; Importer Freemarker.Template.TemplatesCalarmodel; / ** * Classe de résolution de balise personnalisée * @Author Administrator * * / public class ContentDirective implémente templateDireCtiveModel {private static final String param_name = "name"; chaîne finale statique privée param_age = "âge"; @Override public void Execute (Environment Env, Map Params, TemplateModel [] LOOPVARS, TemplateDirectiveBody Body) lève TemplateException, ioException {if (body == null) {Throw New TemplateModeLexception ("Null Body"); } else {String name = getString (param_name, params); Integer Age = getInt (param_age, params); // Après avoir reçu les paramètres, vous pouvez effectuer des opérations spécifiques en fonction de l'opération spécifique, puis afficher les données de la page. if (name! = null) {env.setVariable ("output", default_wrapper.wrap ("Les paramètres obtenus à partir de la classe d'analyse de contenu sont:" + name + ",")); } if (age! = null) {Env.setVariable ("append", default_wrapper.wrap ("Age:" + Age)); } Writer out = env.getout (); out.write ("d'ici, vous pouvez voir le contenu spécifique de la page, tout comme l'opération Document.Writer Write. <br/>"); body.render (out); / * Si vous faites attention, vous constaterez que la page affiche l'instruction de sortie out.write (), puis publiez le contenu de la sortie. On peut voir que lorsque le corps analyse, il mettra d'abord les paramètres dans l'env, et uniquement lorsque la page rencontrera la forme correspondante, elle obtiendra la valeur. Cependant, si le formulaire n'existe pas, une erreur sera signalée. Je pense que le freemarker n'est pas bien fait ici, et l'erreur sera exposée à la page lors de l'analyse. Vous pouvez compenser $ {Output! "Null"} de cette manière, et vous pensez toujours qu'il n'est pas aussi bon que l'expression EL. * /}} / ** * Obtenez la valeur du paramètre de type String * @param paramname * @param parAmmap * @return * @throws templateModeLexception * / public static string getString (String ParamName, map <string, templateModel> Parammap) lance templemodeLexception {templatemodel modèle = Parammap.get (paramname); if (modèle == null) {return null; } if (modèle instanceof templatesCalAmModel) {return ((templatesCalarmodel) modèle) .getAsstring (); } else if (modèle instanceof templaTenumberModel) {return ((templaTenumberModel) modèle) .getAsNumber (). toString (); } else {Throw New TemplateModeLException (paramname); }} / ** * * Obtenez le paramètre de type int * @param paramname * @param parammap * @return * @throws templateModeLexception * / public static Integer gentInt (String ParamName, map <string, templatemodel> Parammap) throws templateModeLexception {templateModel Model = Parammap.get (paramname); if (modèle == null) {return null; } if (modèle instanceof TemplatesCalAmModel) {String str = ((TemplatesCalAmModel) modèle) .getAsstring (); essayez {return Integer.ValueOf (str); } catch (NumberFormatexception e) {Throw New TemplateModeLexception (paramname); }} else if (modèle instanceof templaTenumberModel) {return ((templaTenumberModel) modèle) .getAsNumber (). IntValue (); } else {Throw New TemplateModeLException (paramname); }}}Puis ajouter:
// TAG CUSTOM PARSING PARAMMAP.PUT ("Content", new ContentDirective ());De cette façon, il peut essentiellement être utilisé. Freemarker complète les balises personnalisées pour résoudre le problème de la rédaction de la logique métier simple. Cependant, il est impossible de le faire dans des projets réels, car il n'a pas encore été intégré au printemps, et vous devez mettre l'instance d'analyse de la classe d'analyse dans le temps d'analyse. .