FreeMarker

Posted Vodka~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FreeMarker相关的知识,希望对你有一定的参考价值。

一.概念:一款模板引擎,一种基于模板和要改变的数据,用来生成输出文本(html网页,电子邮件,配置文件,源代码等)的通用工具,属于Java类库。

二. 初衷是用来生成HTML WEB 页面, 特别是基于MVC模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给FreeMarker来输出。FreeMarker不是Web应用框架,而是web应用框架的一个组件。

三.
-新建Maven Web项目
-配置坐标依赖和部署插件

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

   <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>3.1.0</version>
   </dependency>
<!--FreeMarker-->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.23</version>
    </dependency>
  </dependencies>
 -修改配置文件  web.xml , 添加freemarker相关的servlet配置
<?xml version="1.0" encoding="UTF-8"?>
<!--这里的web.xml配置要修改为最新版本,原版本不可用-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>securityannotation</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
<!--  FreeMarker的Servlet配置-->
  <servlet>
      <servlet-name>freemarker</servlet-name>
      <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
      <init-param>
            <!--  模板路径 -->
           <param-name>TemplatePath</param-name>
            <!-- 默认在webapp目录下查找对应的模板文件-->
           <param-value>/</param-value>
      </init-param>

    <init-param>
      <!--    默认编码UTF-8     -->
      <param-name>default_encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </servlet>
  <!-- 处理所有以  .ftl结尾的文件; ftl是freemarker默认的文件后缀 -->
   <servlet-mapping>
       <servlet-name>freemarker</servlet-name>
       <url-pattern>*.ftl</url-pattern>
   </servlet-mapping>
</web-app>

-编写Servlet类
-新建模板文件ftl
-启动项目
-访问项目

四,
-FreeMarker数据类型:
1.布尔型: 等价于Boolean,但是不能直接输出,可转换为字符串输出。
2.日期型: 等价于Date,不能直接输出,需转换成字符串输出。
3.数值型:等价于 int, float, double 等数值类型,有三种显示形式:数值型,货币型,百分比型
4.字符型: 等价于java 中的字符串。
5.sequence类型: 等价于数组, list,set等集合类型。
6.hash类型: 等价于Map类型。

-设置数据:
布尔型:
request.setAtttribute(“flag”,true);

    日期型:
       request.setAttribute("Today",new Date());
 
    数值型:
        request.setAttribute("age",18);
        request.setAttribute("salary",20800.5445);
        
    字符串类型:
    request.setAttribute("MyString","     FreeMarker Test");
     
     序列类型(set,list,数组):
         String [] MusicArray = new String[]"一路向北","不能说的秘密","枫","稻香";
     
     List<String> AddressLists = new ArrayList<>();
     AddressLists.add("广州");
     AddressLists.add("深圳");
     AddressLists.add("北京");
     AddressLists.add("上海");
     AddressLists.add("南京");

     List<User>  AuthorLists = new ArrayList<> ();     //Bean类型
     AuthorLists.add(new User("周杰伦",18));
     AuthorLists.add(new User("薛之谦",28));
     AuthorLists.add(new User("王嘉尔",20));
     AuthorLists.add(new User("Adel",26));
     AuthorLists.add(new User("叶聪明",19));
     
     request.setAttribute("MusicArray",MusicArray);
     request.setAttribute("AddressLists",AddressLists);
     request.setAttribute("AuthorLists",AuthorLists);
   
     hash类型:
         Map<String , String> CityMap = new HashMap<>();
	        CityMap.put("ShangHai","上海");
	        CityMap.put("PeKing","北京");
	        CityMap.put("ShenZhen","深圳");
	        CityMap.put("GuangZhou","广州");
	        CityMap.put("XiaMen","厦门");
	        request.setAttribute("CityMap",CityMap);

-获取数据:
布尔型:
$flag?c
$flag?string
$flag?string(“yes”,“no”) (已废弃)
$flag?then(“勇往直前!”,“回头是岸!”)

    日期型:
           $Today?datetime    //年月日时分秒
          $Today?date          //年月日
          $Today?string("yyyy年mm月dd日 HH:mm:ss")     //自定义格式
 
    数值类型:
        $avg?c
        $avg?string.percent
	  $avg?string.currency
	  $avg?string["0.##"]    //几个“#”号,就代表保留几位小数
   
    字符串型:
           $MyString?substring(0,3) <br>    截取字符串,左闭右开
           $MyString?uncap_first <br>    首字母小写输出
            $MyString?cap_first <br>       首字母大写输出
			$MyString?lower_case <br>   小写输出
			$MyString?upper_case <br>    大写输出
			$MyString?length <br>            字符串长度
			$MyString?starts_with("Free")?string("Start with FreeMarker","Not start with FreeMarker")  是否以指定字符开头(boolean类型)
			$MyString?ends_with("Marker")?string("Ends with FreeMarker","Not Ends with Marker")  是否以指定字符结尾(boolean类型)
			$MyString?index_of("Mar") <br>        获取指定字符的索引
			$MyString?trim <br>              去除字符串前后空格
			$MyString?replace("Free","Vodka") <br>         替换指定字符串

 空值类型:
         不存在的值会直接报错,FreeMarker无法辨别null值,空字符串可以进行判断
        $NullValue!             !:指定确实变量的默认值
		$NullValue!"This string is empty!"     判断变量是否存在,不存在则输出默认语句
		$(NullValue??)?string("Not empty!","Empty!")      ??: 判断字符串是否为空,返回布尔类型,若要输出,需要将布尔类型转换成字符串

序列类型(数组,List,Set):
        通过 list 指令输出序列:
              <#list  序列名  as  元素名>
                      $元素名
              </#list>
              $序列名?size       获取序列长度
              $元素名?index     获取序列元素下标
              $序列名?first        获取第一个元素
              $序列名?last        获取最后一个元素
             <#list  序列名?reverse  as  元素名>
                      $元素名
              </#list>         倒序输出
              
              <#list  序列名?sort  as  元素名>
                      $元素名
              </#list>         升序输出
              
              <#list  序列名?sort?reverse  as  元素名>
                      $元素名
              </#list>         降序输出
              
              若是要根据Bean的某个元素进行排序,就得用函数    sort_by("age") ; 
          
      Hash  类型:
               key 遍历输出:
          <#list hash?keys as key>
               $key  ---  $hash[key]
          </list>

       value 遍历输出:
           <#list hash?values  as value>
               $value
           </list>

五, FreeMarker常见指令
1. assign: 自定义变量指令,可以用该指令创建一个新的变量,或者替换一个已经存在的变量。(单双标签均可)
<#assign 变量名=值>
<#assign 变量名=值 变量名=值> (定义多个变量)

 2.if  elseif  else  逻辑判断指令:
      <# if condition>
          ...
      <elseif  condition2>
          ....
       <elseif  condition3>
        .....
        <#else>
          ...
         </#if>        
          (gt: greater than  , lt :  less than )

       例子: 判断数据是否存在
           <#if  MyLists??>
                 <h1> 数据存在</h1>
                 <#else>
                  <h2>数据不存在</h2>
           </#if>
      
      3.用 macro 指令自定义一些指令,自定义指令可以包含字符串,也可以包含内置指令:
			      1.基本使用:
			            定义:
			            <#macro 指令名>
			                指令内容
			            </#macro>
			            使用:
			            <@指令名></@指令名>
			            
			            2.有参数的自定义指令
			            定义:
			            <#macro 指令名  参数一 参数二>
			                指令内容
			            </#macro>
			            
			            使用:
			             <@指令名 参数一=赋值一 参数二=赋值二></@指令名>
             
                        例子:
                                <#macro QueryUser (UserName , Age)>
								    选手: ---  $UserName  <br>
								    年龄: ---  $Age  <br>
								</#macro>
								
								<@QueryUser UserName='Vodka' Age = 18></@QueryUser>
                                --------------------------------------------------------------------------------
                          		<#--打印九九乘法表-->
								<#macro MultiplicationTable (NumSequence)>
								    <#if NumSequence??>
								        <h1>数列存在,并打印相应乘法表: </h1>   <br>
								        <#list 1..NumSequence as i>
								            <#list 1..i as j>
								                $j * $i = $i*j &nbsp; &nbsp;
								            </#list>
								            <br>
								        </#list>
								    </#if>
								</#macro>
								
								<@MultiplicationTable NumSequence=10></@MultiplicationTable>

4.nested 占位指令:该指令用于执行自定义指令开始和结束标签中间的模板片段,嵌套的片段可以包含模板中任意合法的内容
,即 nested 相当于占位符,一般结合 macro 指令一起使用,将nested 指令置于 macro 指令中,在调用macro 指令时,可以填充 nested 指令所占用的文本域。
<#macro test>
这是一段文本
<#nested>
<#nested>
</#macro>
<@test>

这是填充的文本内容!

/@test

5.import 导入指令:
-引入一个库,即创建一个新的命名空间,然后在那个命名空间中执行给定的路径模板,可以引入空间中的指令。
例如,创建一个公共的指令文件 commons.ftl , 里面有各种各样的自定义指令和组合指令,要使用的时候调用即 可。
<#import “commons.ftl” as common> //引入指令
<@common.Multiplication>/@common.Multiplication //使用指令

6.include 指令:
该指令用于在当前模板中,插入另一个已存在的FreeMarker 模板文件,被包含模板的输出格式是在 include 标签出现的位置插入,被包含的文件和包含的模板共享变量。
<#include “test.html”>
<#include “test.txt”>
<#include “test.ftl”>

7.函数指令:
定义:
<#function AVG x y>
<#return (x+y) / 2>
</#function>
使用:
$ AVG(10,20)

8.swit,case,break等等。

9.FreeMarker 页面静态化:
FreeMarker是一种基于模板,用来生成输出文本的通用工具,所以要制定符合自己业务的模板,生成专属页面。Freemarker是通过 freemarker.template.Configuration 对象(在整个应用中保证是唯一实例)进行模板加载(处理创建和缓存解析),用户再通过 getTemplate方法获得想要的模板。
步骤:
一,创建模板: 例如 , MyTemplate.ftl;
二,获取模板对象:
1.实例化模板对象:
Configuration cfg = new Configuration();
2.设置加载模板的上下文,以及加载模板的路径 (模板存放路径)
cfg.setServletContestForTemplateLoading(getServletContext() , “/template”);
3.设置模板编码格式
cfg.setDefaultEncoding(“UTF-8”);
4.加载模板文件 ,获取模板对象:
Template template = cfg.getTemplate(“MyTemplate.ftl”);

三,设置数据模型(可以是任意数据类型):
Map<String,Object> MyMap = new HashMap<>();
MyMap.put(“title”,“XXXXX”);
MyMap.put(“name”,“XXXXX”);
MyMap.put(“content”,“XXXXX”);

四,生成html
1.获取项目的根目录:
String basePath = request.getServletContext().getRealPath("/");
2.设置即将生成的html的存放路径:
File htmlFile = new File(basePath + “/html”);
3.判断 目录是否已经存在
if(!htmlFile.exists())
htmlFIle.mkdir();

4.得到生成文件名(唯一的文件名)
String fileName = System.currentTimeMillis() + “.html”;
5.创建html文件
File file = new File(htmlFile ,fileName);
6.获取文件输出流:
FileWriter writer = new FileWriter(file);
7.生成:
template.process(MyMap,writer);
writer.flush();
writer.close();

10.算术运算符:自行查阅文档

以上是关于FreeMarker的主要内容,如果未能解决你的问题,请参考以下文章

如何从源代码构建 freemarker?

如何在 Maven 中使用模板代码生成器(例如 freemarker)?

FreeMarker自定义指令--代码实现

SpringBoot获取Freemarker模板引擎,生成HTML代码

FreeMarker里如何调用java代码?

java工程中使用freemarker例子