模板引擎Freemarker基础知识

  • Freemarker是什么

  • FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。
    • 常用的java模板引擎还有 Jsp、Freemarker、Thymeleaf 、Velocity 等。

      freemarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件)

      freemarker作为springmvc一种视图格式,默认情况下SpringMVC支持freemarker视图格式。

      FreeMarker 基础指令

      map即为freemarker静态化所需要的数据模型

      List指令

      1、注释,即:<#‐‐被注释的内容‐‐>

      2、插值(Interpolation):即 ${…} 部分,freemarker会用真实的值替换 ${…} 中的内容

      3、FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。例如:<#list stuMap?keys as k> ,就是获取stuMap中的所有的key作为一个list集合,然后取list集合中的一个key赋值给k.

      4、文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容。

      解释Demo:

      <#list stus as stu>
              <tr>
                  <td>${stu_index + 1}</td>
                  <td>${stu.name}</td>
                  <td>${stu.age}</td>
                  <td>${stu.mondy}</td>
              </tr>
          </#list>

      其中:

      _index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始

    • 遍历Map数据

    • 姓名:${stuMap['stu1'].name}<br/>
      或者
    • 姓名:${stuMap.stu1.name}<br/>

      其中stuMap是一个map集合,stu1是map集合中的一个元素对象,name是stu1的一个属性,如果采用list集合去遍历的话,第二种方法就不适用了。

    • if指令

    • if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。
      例如:
    • <td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td>

      意思就是如果stu的姓名是小明的话,就加背景色

    • 其它指令

    • 运算符

      1、算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , %

      2、逻辑运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误

      3、比较运算符 表达式中支持的比较运算符有如下几个: 1 =或者==:判断两个值是否相等. 2 !=:判断两个值是否不等. 3 >或者gt:判断左边值是否大于右边值 4 >=或者gte:判断左边值是否大于等于右边值 5 <或者lt:判断左边值是否小于右边值 6 <=或者lte:判断左边值是否小于等于右边值

      注意: =和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,“x”,"x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>

      空值处理

      1、判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false

      例如:

    • <#if stus??>
          <#list stus as stu>
           ......    
          </#list>
          </#if>

      意思就是:如果stus集合不为空就遍历

      2、缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。

      例: ${name!’’}表示如果name为空显示空字符串。

      如果是嵌套对象则建议使用()括起来。

      例如: ${(stu.bestFriend.name)!’’}表示,如果stu或bestFriend或name为空默认显示空字符串。

    • 内建函数

    • 内建函数语法格式: 变量+?+函数名称
      例如:
      1、和到某个集合的大小
      ${集合名?size}
      2、日期格式化
    • 显示年月日: ${today?date}
      显示时分秒:${today?time}  
      显示日期+时间:${today?datetime} <br>       
      自定义格式化:  ${today?string("yyyy年MM月")}

      3、内建函数c

      map.put(“point”, 102920122);

      point是数字型,使用${point}会显示这个数字的值,不并每三位使用逗号分隔。

      如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出

      ${point?c}

      4、将json字符串转成对象

      一个例子:

      其中用到了 assign标签,assign的作用是定义一个变量。

    • <#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
      <#assign data=text?eval />
      开户行:${data.bank}  账号:${data.account}

      一般这种语法不会用

    • 入门Demo

      要导入的依赖

    • <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-freemarker</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
              </dependency>
              <dependency>
                  <groupId>com.squareup.okhttp3</groupId>
                  <artifactId>okhttp</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.apache.commons</groupId>
                  <artifactId>commons-io</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
              </dependency>
          </dependencies>

      配置文件

    • server:
        port: 8088 #服务端口
      spring:
        application:
          name: test-freemarker #服务名
        freemarker:
          cache: false #关闭模板缓存,及时改及时测
          settings:
            template_update_delay: 0 #检查模板更新延迟时间,例如设置为1秒,就是1秒后检查模板是否更新,设置为0表示立即检查,

      模型类

    • @Data
      public class Student {
          private String name;//姓名
          private int age;//年龄
          private Date birthday;//生日日期
          private Float money;//金额
          private List<Student> friends;//朋友
          private Student bestFriend;//最好的朋友
      }

      创建模板

    • <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf‐8">
          <title>Hello World!</title>
      </head>
      <body>
      Hello ${name}!
      <br/>
      遍历数据模型中的list学生信息,(数据模型中的名称为stus)
      <table>
          <tr>
              <td>序号</td>
              <td>姓名</td>
              <td>年龄</td>
              <td>金额</td>
              <td>出生日期</td>
          </tr>
          <#--判断list集合是否为空,为空就不执行-->
          <#if stus??>
              <#list stus as stu>
              <tr>
                  <td>${stu_index+1}</td>
                  <td <#if stu.name == '小明'>style="background-color: cyan" </#if>>${stu.name}</td>
                  <td>${stu.age}</td>
                  <td <#if (stu.money > 300)>style="background: red" </#if>>${stu.money}</td>
                  <td>${stu.birthday?date}</td>
              </tr>
          </#list>
          </#if>
      </table>
      <br/>
      学生的个数:${stus?size}
      <br/>
      遍历数据模型中的stuMap(map数据),第一种方法,在中括号中填写map的key;第二种方法,在map后面直接加 "."
      <br/>
      姓名:${(stuMap['stu1'].name)!''}<br/><#--如果stu1用户存在就显示,否则就显示一个空字符串-->
      年龄:${(stuMap['stu1'].age)!''}<br/>
      金额:${(stuMap['stu1'].money)!''}<br/>
      姓名:${(stuMap.stu1.name)!''}<br/>
      遍历map中的key,用list标签,stuMap?key就是一个key列表(是一个list)<br/>
      <#list stuMap?keys as k>
          姓名:${stuMap[k].name}<br/>
          年龄:${stuMap[k].age}<br/>
      </#list>
      <br/>
      <#--?c的作用就是去掉每三位数字一个分隔符-->
      ${point?c}
      <br/>
      <#assign text="{'bank':'工商银行','account':'101920201920212'}" />
      <#--?eval的作用就是把text的json字符串转为Java对象-->
      <#assign data=text?eval />
      开户行:${data.bank} 账号:${data.account}
      </body>
      </html>

      接口数据

    • @RequestMapping("/test1")
          public String test1(Map<String, Object> map){
              //map就是freemarker模板所使用的数据
              map.put("name", "好好学习!");
      
              Student stu1 = new Student();
              stu1.setName("小明");
              stu1.setAge(18);
              stu1.setMoney(1000.86f);
              stu1.setBirthday(new Date());
              Student stu2 = new Student();
              stu2.setName("小红");
              stu2.setMoney(200.1f);
              stu2.setAge(19);
              stu2.setBirthday(new Date());
              List<Student> friends = new ArrayList<>();
              friends.add(stu1);
              stu2.setFriends(friends);
              stu2.setBestFriend(stu1);
              List<Student> stus = new ArrayList<>();
              stus.add(stu1);
              stus.add(stu2);
              //向数据模型放数据
              map.put("stus",stus);
              //准备map数据
              HashMap<String,Student> stuMap = new HashMap<>();
              stuMap.put("stu1",stu1);
              stuMap.put("stu2",stu2);
              //向数据模型放数据
              map.put("stu1",stu1);
              //向数据模型放数据
              map.put("stuMap",stuMap);
      
              map.put("point",102920122);
      
              //返回freemarker模板的位置,基于resources/templates路径的,freemarker会从resources/templates下面找
              return "test1";//这个只能是不带后缀的文件名
          }

      使用模板文件静态化

    • public void getGenerateTest() throws IOException, TemplateException {
              //获取配置
              Configuration configuration = new Configuration(Configuration.getVersion());
      
              //获取模板
              //获取模板路径
              String path = this.getClass().getResource("/").getPath();
              configuration.setDirectoryForTemplateLoading(new File(path + "/templates/"));
              //获取模板文件
              Template template = configuration.getTemplate("test1.ftl");
      
              //获取数据模型
              Map modelMap = getModelMap();
              //静态化,生成html页面
              String templateIntoString = FreeMarkerTemplateUtils.processTemplateIntoString(template, modelMap);
             // System.out.println(templateIntoString);
              InputStream inputStream = IOUtils.toInputStream(templateIntoString);
              FileOutputStream outputStream = new FileOutputStream(new File("D:/else/test.html"));
              IOUtils.copy(inputStream,outputStream);
              //关流
              inputStream.close();
              outputStream.close();
      
          }

      使用模板字符串静态化

    • public void getGenerateTestByString() throws IOException, TemplateException {
              //获取模板字符串
               String templateString="" +
                  "<html>\n" +
                  "    <head></head>\n" +
                  "    <body>\n" +
                  "    名称:${name}\n" +
                  "    </body>\n" +
                  "</html>";
              //生成模板
              Configuration configuration = new Configuration(Configuration.getVersion());
              //获取模板加载器
              StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
              //把字符串模板放入模板加载器中
              stringTemplateLoader.putTemplate("template", templateString);
              //设置模板加载器
              configuration.setTemplateLoader(stringTemplateLoader);
              //转成模板
              Template template = configuration.getTemplate("template", "utf-8");
      
              //获取模型数据
              Map modelMap = getModelMap();
      
              //静态化
              String templateIntoString = FreeMarkerTemplateUtils.processTemplateIntoString(template, modelMap);
              InputStream inputStream = IOUtils.toInputStream(templateIntoString);
              FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/else/test2.html"));
              IOUtils.copy(inputStream, fileOutputStream);
              fileOutputStream.close();
              inputStream.close();
      
          }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序。虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据。 FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件。FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境。FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库。而且你还可以通过Eclipse的插件来编辑FreeMarker,经过验证,FreeMarker 最好的 Eclipse 编辑插件是 JBoss Tools。 FreeMarker是免费的。 FreeMarker特性: 1、通用目标 能够生成各种文本:HTML、XML、RTF、Java源代码等等 易于嵌入到你的产品中:轻量级;不需要Servlet环境 插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等 你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器 2、强大的模板语言 所有常用的指令:include、if/elseif/else、循环结构 在模板中创建和改变变量 几乎在任何地方都可以使用复杂表达式来指定值 命名的宏,可以具有位置参数和嵌套内容 名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突 输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换 3、通用数据模型 FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示 你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰 4、为Web准备 在模板语言中内建处理典型Web相关任务(如HTML转义)的结构 能够集成到Model2 Web应用框架中作为JSP的替代 支持JSP标记库 为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员 5、智能的国际化和本地化 字符集智能化(内部使用UNICODE) 数字格式本地化敏感 日期和时间格式本地化敏感 非US字符集可以用作标识(如变量名) 多种不同语言的相同模板 6、强大的XML处理能力 <#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树 在模板中清楚和直觉的访问XML对象模型 开源论坛 JForum 就是使用了 FreeMarker 做为页面模板。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值