首页 > 其他分享 >Freemarker--学习笔记

Freemarker--学习笔记

时间:2024-12-19 16:03:24浏览次数:5  
标签:string Freemarker -- 模版 笔记 运算符 指令 FreeMarker 模板

目录

前言

二、Freemarker 数据类型

1.布尔类型

2.日期类型

3.数值类型

4.字符串类型

5.sequence类型

6.序列类型(数组、List、Set)

6.1数组

6.2集合

6.1hash

三、Freemarker 常见指令

1.assign 自定义变量指令

2.if elseif else 逻辑判断指令

3.list 遍历指令

4.macro 自定义指令

5.nested 占位符指令

6.import 指令

7.include 包含指令

四、Freemarker 页面静态化

1.定义模板

2.加载模版

3.生成对应的html文件

五、Freemarker 运算符

1.算数运算符 

2.逻辑运算符

3. 比较运算符

4.空值运算符

总结


前言

Freemarker学习笔记。


一、Freemarker 概述

        FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。是一个Java类库。
        FreeMarker 被设计用来生成 HTMLWeb 页面,特别是基于 MVC 模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给 FreeMarker 来输出。虽然 FreeMarker 具有一些编程的能力,但通常由Java 程序准备要显示的数据,由FreeMarker 生成页面,通过模板显示准备的数据(如下图):        

        FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件。
        FreeMarker与容器无关,因为它并不知道HTTP或Servlet。FreeMarker同样可以应用
于非Web应用程序环境。
        FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在板中使用JSP标记库。

二、Freemarker 数据类型

1.布尔类型

        布尔型:等价于Java中的 boolean 类型,不同的是不能直接输出,可转化为字符串输出。

        布尔类型不能在模板中直接使用,需要使用c、string、string('true','false')等方法进行转换。

//设置数据(给模版设置数据)
    req.setAttribute("flag",false);
//模版
  ${flag?c}
  ${flag?string}
  ${flag?string('对了','错了')}

2.日期类型

        日期型:等价于Java中的 Date 类型,不同的是不能直接输出,需要转换成字符串再输出。

        日期类型不能在模板中直接使用,需要使用string('yyyy.MM.dd HH:mm:ss')、date、time、datetime等方法进行转换。

//设置数据(给模版设置数据)  
    req.setAttribute("date",new Date());
//模版 
<#-- 自定义时间输出格式。-->
  ${date?string('yyyy.MM.dd HH:mm:ss')}</br>
<#--仅日期部分,没有一天当中的时间部分。-->
  ${date?date}</br>
<#--仅一天当中的时间部分,没有日期部分。-->
  ${date?time}</br>
<#--日期和时间都在-->
  ${date?datetime}

3.数值类型

        等价于 Java 中的 int,float,double 等数值类型。有三种显示形式:数值型(默认),货币型(string.currency),百分比型(string.percent)。

 //设置数据(给模版设置数据)
    req.setAttribute("numberId",532930);
    req.setAttribute("age",24);
    req.setAttribute("avg",0.253);
//模版
<#--将数值转化为字符串类型-->
        ${numberId?c}<br>
        <#--将数值转换为货币类型-->
        ${age?string.currency}<br>
        <#-- 将数值转换为百分百类型-->
        ${avg?string.percent}<br>    

4.字符串类型

等价于Java中的字符串,有很多内置函数。

//设置数据(给模版设置数据)
req.setAttribute("name","陈清零");
//模版
   <#--字符串长度-->
   ${name?length}<br>
   <#--提取字符串前两个字符并输出。-->
   ${name?substring(0,2)}<br>
   <#--将字符串转换为小写并输出。-->
   ${name?lower_case}<br>
   <#--将字符串的首字母大写并输出-->
   ${name?cap_first}<br>

5.sequence类型

        FreeMarker 的变量必须赋值,否则就会抛出常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。

         FreeMarker 提供两个运算符来避免空值:
1.   ! : 指定缺失变量的默认值
        ${ value! } : 如果value值为空,则默认值是空字符串
        ${ value! "默认值" } : 如果value值为空,则默认值是字符串"默认值"
2.   ?? : 判断变量是否存在
        ${ (value??) ?string } : 如果变量存在,返回 true,否则返回 false

${CD!"CD不存在"}<br>
${(CD??)?string}

6.序列类型(数组、List、Set)

6.1数组

遍历数组:通过list指令输出序列
<#list 序列名 as 元素名>
${元素名}
</#list>

获取序列的长度:${序列名?size}
获取序列元素的下标:${元素名?index}
获取第一个元素:${序列名?first}
获取最后一个元素:${序列名?last}

//设置数据(给模版设置数据)
String[] strs={"java","c++","python","c"};
req.setAttribute("strs",strs);

//模版
<#list strs as item>
    下标:${item?index}-课程名称:${item}<br>
</#list>
数组长度:${strs?size}<br>
第一个元素:${strs?first}<br>
最后一个元素:${strs?last}<br>

6.2集合

遍历集合:通过list指令输出序列
<#list 序列名 as 元素名>
${元素名}
</#list>

倒序输出:序列名?reverse

升序输出:序列名?sort

降序输出:序列名?sort?reverse

//设置数据(给模版设置数据)
List<String> list= Arrays.asList("云南","贵州","四川","重庆");
req.setAttribute("list",list);

//模版
<#list list as item>
${item} -
</#list><br>

<#--倒序输出  序列名?reverse-->
倒序输出:
<#list list?reverse as item>
${item}
</#list><br>

<#--升序输出 序列名?sort-->
升序输出:
<#list list?sort as item>
${item}
</#list><br>

<#--降序输出 序列名?sort?reverse-->
降序输出:
<#list list?sort?reverse as item>
${item}

</#list>

遍历Java对象

//设置数据(给模版设置数据)
//java 对象
List<Student> stu= new ArrayList<>();
stu.add(new Student(1,"张三",18,"北京市","12345678901","计算机网络1班"));
stu.add(new Student(2,"李四",16,"北京市","12345678901","人工智能1班"));
stu.add(new Student(3,"王五",24,"北京市","12345678901","大数据网络1班"));
req.setAttribute("stu",stu);

//模版
<#--遍历java对象-->
<#list stu?sort_by("age")?sort?reverse as student>
  <li>
      学号:${student.id}
      姓名:${student.name}
      年龄:${student.age}
      地址:${student.address}
      手机号:${student.phone}
      班级:${student.className}
  </li>
</#list>

6.1hash

遍历hash

法一:key遍历输出
<#list 序列名?keys as key>
        ${key} -- ${hash[key]}
</#list>

法二:value遍历输出

<#list 序列名?values as value>
        ${value} 
</#list>

//设置模版(给模版设置数据)
Map<String, Object> map = new HashMap<>();
   map.put("id",1);
   map.put("name","塔斯汀");
   map.put("age",18);
   map.put("sex","男");
   req.setAttribute("ttmap",map);

//模版
<#-- 法一 -->
<#list ttmap?keys as key >
    ${key}:${ttmap[key]}
</#list><br>

<#-- 法二 -->
<#list ttmap?values as value >
    ${value}
</#list><br>

<#-- 法三 -->
<#list ttmap as key,value>
    ${key}:${value}
</#list>

三、Freemarker 常见指令

1.assign 自定义变量指令

语法:
<#assign 变量名=值>
<#assign 变量名=值 变量名=值>(定义多个变量)

<#assign name="张三" age=18 love=["红","蓝","黄"]>
    ${name}-${age}
<#list love as item>
    ${item}
</#list>

2.if elseif else 逻辑判断指令

格式:
    <#if condition>
    <#elseif condition2>
    <#elseif condition3>
    <#else>
    </#if>

注:
1.condition,condition2等,将被计算成布尔值的表达式。
2.elseif 和 else 指令 是可选的。

<#assign score=80>
<#if score<60>
     考试不及格
<#elseif score gt 60 && score lt 80>
     考试及格
<#else>
     考试优秀
</#if>

3.list 遍历指令

    格式1:
        <#list sequence as item>
        </#list>

    格式2:
        <#list sequence as item>
        <#else>
当没有选项时,执行else指令    
        </#list>
注:
1.else 部分是可选的
2.sequence: 想要迭代的项,可以是序列或集合的表达式
3.item: 循环变量 的名称
4.当没有迭代项时,才使用 else 指令,可以输出一些特殊的内容而不只是空在那里。

<#assign list1=[1,2,3,4,5,6,7,8,9,10]>
<#assign list2=["张三","李四","王五","赵六","钱七","马八","黄九","周十"]>
<#assign list3=[]>

<#list list1 as item>
     ${item}、
</#list><br>
<#-- 判断数据不为空,再执行遍历。当序列没有数值时,使用默认信息-->

<#if list7??>
    <#list list7 as item>
       ${item}
    </#list>
<#else>
    没有数据遍历list2:&nbsp;
    <#list list2 as item>
       ${item}
    </#list>
</#if>

4.macro 自定义指令

macro自定义指令(宏)
    1.基本使用
    格式:
        <#macro 指令名>
            指令内容
        </#macro>

    使用:
        <@指令名></@指令名>
    2.有参数的自定义指令
    格式:
        <#macro 指令名 参数名1 参数名2>
            指令内容
        </#macro>

    使用:
        <@指令名 参数名1=参数值1 参数名2=参数值2></@指令名>
    注
        1.指令可以被多次使用。
        2.自定义指令中可以包含字符串,也可包含内置指令-->

//用法一 自定义无参数指令
<#macro patent>
  © 1999–2015 The FreeMarker Project. All rights reserved.
</#macro>
<#macro patent02>
   嵌套自定义指令<@patent/>
</#macro>

<@patent/><br>
<@patent02/>

//用法二 自定义有参指令
<#macro customerInformation name age ddress>
   <p>姓名:${name}</p>
   <p>年龄:${age}</p>
   <p>地址:${ddress}</p>
</#macro>

<@customerInformation name="李四" age="19" ddress="北京市" />

<#--九九乘法表-->
        <#macro jj>
            <#list 1..9 as i>
                <#list 1..i as j>
                    ${j} * ${i} = ${i*j} &nbsp;
                </#list>
                <br>
            </#list>
        </#macro>
<@jj/>

5.nested 占位符指令

        nested 相当于占位符,一般结合macro指令一起使用。可以将自定义指令中的内容通过nested指令占位,当使用自定义指令时,会将占位内容显示。

<#macro text>
   问君何能尔<#nested>
</#macro>

<@text/><br>
<@text>心远地自偏</@text>

6.import 指令

import 指令用于导入其他模板文件,并使用导入的模板文件中定义的变量。
import 指令的格式:
    <#import "模板文件路径" as 指令名>
使用:
    <@指令名.变量名/>

// f04.ftl
  <#--九九乘法表-->
        <#macro jj>
            <#list 1..9 as i>
                <#list 1..i as j>
                    ${j} * ${i} = ${i*j} &nbsp;
                </#list>
                <br>
            </#list>
        </#macro>
<@jj/>

//f03.ftl
<#import "/template/f04.ftl" as f04>
<@f04.jj/>

7.include 包含指令

        可以使用 include 指令在你的模板中插入另外一个 FreeMarker 模板文件。 被包含模板的输出格式是在include 标签出现的位置插入的。 被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。

 <#include "f04.ftl" >

四、Freemarker 页面静态化

        通过上述介绍可知 Freemarker 是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板,然后生成自己的 html页面。

        Freemarker 是通过freemarker.template.Configuration 这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过 getTemplate 方法获得你想要的模板,有一点要记住freemarker.template.Configuration 在你整个应用必须保证唯一实例。

        应用场景:页面上的数据基本不会变,变化频率不高。例如购物平台上的商品分类、新闻发布后的内容等。

1.定义模板

news.ftl

 <#--新闻标题-->
<h4 align="center">${title}</h4>
<#--新闻来源  发布时间-->
<p align="center">
<#--本报记者-->
本报记者&nbsp;${author}<br>
新闻来源:${source} &nbsp;发布时间:${date?string('yyyy.MM.dd HH:mm:ss')}
</p>
<#--新闻内容-->
<p style="text-align: center ;text-indent:2em">
${content}
</p>

2.加载模版

//实例化模版对象
Configuration con= new Configuration();
//设置加载模版的上下文 以及加载模版的路径 (模版存放路径)
con.setServletContextForTemplateLoading(this.getServletContext(),"template");
//设置模版的 编码格式
con.setDefaultEncoding("utf-8");
//加载模版文件 获取模版对象
Template template = con.getTemplate("news.ftl");
//设置数据模型
Map<String, Object> map = new HashMap<>();
map.put("title","家门口有了优质中医药服务(健康焦点)");
map.put("content","今年9月,国家中医药管理局等5部门联合发布《关于加快推进县级中医医院高质量发展的意见》(以下简称《意见》),提出到2025年,80%以上县级中医医院力争达到二级甲等以上中医医院水平,500所左右县级中医医院力争达到三级中医医院水平。\n"+"据统计,目前我国县级中医医院有2000多家,约占公办中医医院的3/4,其诊疗量约占县域中医医疗机构总诊疗量的70%。近年来,我国县级中医医院建设取得一定进展,基础设施条件有所改善,管理水平、人员素质有了进一步提高。深入落实《意见》要求,各地正在努力探索,加快推进县级中医医院高质量发展。\n" +"医疗资源沉下去——\n" + "破解基层医疗服务难题,推进县级中医医院医共体建设");
map.put("author","杨xx 游 x 窦xx");
map.put("source","xx日报");
map.put("date",new Date());

3.生成对应的html文件

//获取项目的根目录
String path = req.getServletContext().getRealPath("/");
//设置html文件存放的路径
File htmlFile = new File(path+"/html");
//判断文件(目录)是否存在
if (!htmlFile.exists()){
//如果不存在就创建
htmlFile.mkdir();
}
//得到生成的文件名(生成随机不重复的文件名)
String fileName = System.currentTimeMillis()+".html";
//创建html文件
File file = new File(htmlFile,fileName);
//获取文件输出流
FileWriter fileWriter = new FileWriter(file);
//生成html(将数据模型填充到模版  中)
try {
      template.process(map, fileWriter);
    } catch (TemplateException e) {
            e.printStackTrace();
    }finally {
            //关闭资源
            fileWriter.flush();
            fileWriter.close();
        }

五、Freemarker 运算符

1.算数运算符 

<#--  +、-、*、/、%-->
<#assign a=3 b=5>
${a} + ${b} = ${a+b}<br>
${a} - ${b} = ${a-b}<br>
${a} * ${b} = ${a*b}<br>
${a} / ${b} = ${a/b}<br>
${a} % ${b} = ${a%b}<br>

2.逻辑运算符

<#--&&、||、! -->
<#assign a=3 b=5 c=15>
<#if a*b=c && a<b>
     &&
</#if>
<#if a==b || a<b>
    ||
</#if>
<#if a!=b >
    !
</#if>

3. 比较运算符

gt : 大于号,推荐使用 gt
lt : 小于号,推荐使用 lt
gte : 大于等于,推荐是用 gte
lte : 小于等于,推荐使用 lte
== : 等于
!= : 不等于

<#assign a=3 b=5 c=15>
 <#if c gt b >
      ${c} 大于 ${b}<br>
 </#if>
 <#if a lt b>
      ${a} 小于 ${b}<br>
 </#if>
 <#if a*b gte c>
     ${a} 乘 ${b} 大于等于 ${c}<br>
 </#if>
 <#if a*b lte c>
     ${a} 乘 ${b} 小于等于 ${c}
 </#if>

4.空值运算符

空值运算符
1. ?? : 判断是否为空,返回布尔类型
    如果不为空返回 false,如果为空返回 true,不能直接输出
    ${(name??)?string}
2. ! : 设置默认值,如果为空,则设置默认值
    1.设置默认为空字符串:
    ${name!}
    2.设置指定默认值
    ${name!'张三'}

<#assign name="">
    ${(name??)?string}
    ${(name2??)?string}
    ${(name2??)?string('存在','不存在')}
    ${name2!"陈清零"}


总结

学习总结笔记。

标签:string,Freemarker,--,模版,笔记,运算符,指令,FreeMarker,模板
From: https://blog.csdn.net/weixin_45694171/article/details/144529993

相关文章

  • 77乐园:千万玩家的游戏乐土社区
    在游戏的浩瀚星空中,77乐园犹如一颗璀璨的明星闪耀其中。它隶属于成都柳暗星河科技有限公司,始终秉持着以玩家为核心的理念,构建起一个独特的游戏平台。一直以来,77乐园都在不懈努力,坚持为玩家奉献最具价值的服务。无论是丰富优质的资讯信息,还是详尽的游戏相关资料、精准的数......
  • 【NLP 16、实践 ③ 找出特定字符在字符串中的位置】
    看着父亲苍老的白发和渐渐老态的面容希望时间再慢一些                                                ——24.12.19一、定义模型1.初始化模型①初始化父类super(TorchModel,self).__init__(): 调用父类nn.Mod......
  • 掌握pnpm Workspace秘诀:轻松管理多个Vue项目,告别混乱!
    个人使用背景:公司多个后台系统想共用同一套ui框架和组件共用,方便使用组件库二次封装的内容,已经一些共用的api,所以使用workspace官方文档:pnpm内置了对单一存储库(也称为多包存储库、多项目存储库或单体存储库)的支持。你可以创建一个工作空间以将多个项目合并到一个仓库中。......
  • Vue零基础教程|从前端框架到GIS开发系列课程(六)组合式API
    前文指路:Vue零基础教程|从前端框架到GIS开发系列课程(五)组件式开发Vue零基础教程|从前端框架到GIS开发系列课程(四)计算属性与侦听器Vue零基础教程|从前端框架到GIS开发系列课程(三)模板语法Vue零基础教程|从前端框架到GIS开发系列课程(二)0帧起手《Vue零基础教程》,从前端框架到G......
  • [深入探讨 Google Cloud SQL for PostgreSQL 的使用:Langchain 集成]
    文章目录概要整体架构流程技术名词解释技术细节小结概要提示:这里可以添加技术概要例如:openAI的GPT大模型的发展历程。整体架构流程提示:这里可以添加技术整体架构例如:在语言模型中,编码器和解码器都是由一个个的Transformer组件拼接在一起形成的。技术......
  • Springboot面试题+个人理解
    应该有相当一部分程序员是通过Springboot接触WEB开发的,但实际上他已经是一个进化到比较后期的框架了。WEB的大部分的功能都不是由Springboot实现的,它只做了一些简化开发的工作。对于倒着学框架的感受其实不怎么好,大部分时间都得保持一个“学了再说,会用就行”的态度,一旦你想......
  • 网络编程一>HTTP协议详解,<一文搞懂HTTP协议,抓包工具使用,HTTP协议报头>
    目录:  一.获取HTTP协议: 二.HTTP基本格式及格式内容: 三.HTTP请求"报头"详情(header):  一.获取HTTP协议:一.HTTP是什么HTTP(全称为"超文本传输协议")是⼀种应用非常广泛的应用层协议. 当我们在浏览器中输入⼀个"网址",此时浏览器就会给对应的服务......
  • 【k8s集群应用】Kubernetes二进制部署实例(master02+负载均衡)+Dashboard
    文章目录配置指南在`master02`节点上部署Kubernetes组件配置负载均衡器(Nginx+Keepalived)在`lb01`和`lb02`节点上操作修改Node节点上的配置文件并使用VIP在`master01`节点上测试Pod的创建和访问DashboardDashboard介绍部署Dashboard上传`recommended.......
  • workman服务端开发模式-应用开发-总架构逻辑说明
    一、后台管理端(操作页面端)    管理员用浏览器打开页面管理端后,页面管理端会自动检测,如果本地cookie不存在的情况下,跳转到登录页面,如果本地cookie存在的情况下,跳转到首页。登录的情况下,就不说,后面在业务架构里面会说明的。    在登录页面输入邮箱账号、密......
  • 《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代
    MilvusCloudBM25:重塑全文检索的未来在最新的MilvusCloud2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了MilvusCloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据库指南》的......