freemarker
创始人
2024-03-25 23:06:40
0

文章目录

  • 创建项目
    • 引入依赖
    • 创建配置文件
    • 创建启动类和测试类
  • 语法
    • list
    • Map
    • if
    • 运算符
    • 处理空值
      • 使用`??`
      • 指定缺失变量默认值
  • 内建函数
    • 集合长度
    • 数据类型
    • 布尔值
    • 时间类型
    • 数值类型
    • 字符串类型
    • sequence序列类型
    • hash类型
  • 常见指令
    • assign自定义变量指令
    • json转成对象
  • 实例
    • list通过下标取值
    • map取值通过list的对象取

创建项目

引入依赖

创建一个maven项目,然后引入依赖


4.0.0org.springframework.bootspring-boot-starter-parent2.4.4 com.wzwspringboot0.0.1-SNAPSHOTspringbootDemo project for Spring Boot1.8org.springframework.bootspring-boot-starter-freemarkerorg.springframework.bootspring-boot-starter-weborg.projectlomboklombokcom.squareup.okhttp3okhttpcommons-iocommons-io2.7org.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-maven-plugin

创建配置文件

配置端口号和模板位置,以及跳转的后缀

server:port: 3031
spring:freemarker:cache: false  #关闭模板缓存template-loader-path: classpath:/templatessuffix: .ftl

创建启动类和测试类

实体类

package com.wzw.springboot.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private Integer age;private String phone;private String address;}

启动类

package com.wzw.springboot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootApplication {public static void main(String[] args) {SpringApplication.run(SpringbootApplication.class, args);}}

controller类

package com.wzw.springboot.controller;import com.wzw.springboot.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.Map;/*** 不要使用RestController,freemarker是需要跳转到对应的ftl,如果使用RestController,就会被转成json,跳转不过去了*/
@Controller
@RequestMapping("/free")
public class FreemarkerController {/*** @param map 这个map最后会响应给用户,ftl中就可以通过这个map取到值* @return*/@RequestMapping("/index")public String hello(Map map){map.put("user",new User("张三",10,"13333333333","一号胡同"));return "hello";}
}

创建ftl,也就是模板,因为配置文件中配置了它的位置是/templates下,所以我们放在resources下的templates中
在这里插入图片描述


ftl测试<#-- 获取map中的值-->hello ${user.name}

然后启动测试,成功访问并取到值
在这里插入图片描述

语法

注释:
html的注释是,而freemarker的注释是<#-- -->,注释中的内容会被freemarker忽略

插值:
freemarker使用${}插值,用真实值替换${},例如${user.name}中的值被map中的值替换
在这里插入图片描述
FTL指令:
freemarker会解析标签中的逻辑或表达式

文本:
仅文本信息,直接输出内容

list

数据模型中存值

    @RequestMapping("/test1")public String test1(Map map){User user1 = new User("张三1", 10, "13333333333", "1号胡同");User user2 = new User("张三2", 20, "00000000001", "2号胡同");User user3 = new User("张三3", 30, "000000000022", "3号胡同");User user4 = new User("张三4", 40, "00000000003", "4号胡同");List users=new ArrayList<>();users.add(user3);users.add(user4);//list放在数据模型中map.put("users",users);HashMap userMap=new HashMap<>();userMap.put("user1",user1);userMap.put("user2",user2);//map放在数据模型中map.put("userMap",userMap);return "test1";}

ftl中取值


test1遍历数据模型中的list数据(数据模型中key为users)<#list users as user><#-- _index获取下标-->
序号姓名年龄电话地址
${user_index}${user.name}${user.age}${user.phone}${user.address}

在这里插入图片描述

Map

        获取数据模型中的userMap
第一种方法,在map后 [key]
姓名:${userMap['user1'].name}
地址:${userMap['user1'].address}
第二种方法,map后 .key
姓名:${userMap.user2.name}
地址:${userMap.user2.address}

遍历map中的key
<#list userMap?keys as key>${key}
遍历map中的value
<#list userMap?values as value>${value}
通过key遍历值,这里只能通过[]的方式
<#list userMap?keys as key>${userMap[key].name}

在这里插入图片描述

if

            <#list users as user>style="color: red"  ><#-- _index获取下标-->${user_index}${user.name}${user.age}${user.phone}${user.address}

生效了

在这里插入图片描述

运算符

  • 算术运算符

freemarker中支持算术运算符:+ - * / %

  • 逻辑运算符
    && 并且
    || 或者
    !
  • 比较运算符
    =或== 判断两个值是否相等
    != 判断两个之是否不相等
    >或gt 大于
    >=或gte大于等于
    <或lt小于
    <=或lte小于等于
    使用大于的比较运算符<#if user.age > 30>报错
    在这里插入图片描述
    换成<#if user.age gt 30>或者使用括号包起来<#if (user.age > 30)>
    在这里插入图片描述

处理空值

不要给users存储值,报错
在这里插入图片描述

使用??

取值时候提前判断非空
使用??,如果存在就是true,如果不存在,就是false

            <#if users??><#list users as user> 30)>style="color: red"  ><#-- _index获取下标-->${user_index}${user.name}${user.age}${user.phone}${user.address}

判断非空后,因为空值,所以没有输出,但是也没有报错了
在这里插入图片描述

        使用 ?? 判断字符串是否为空;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串 :${(name??)?string}

指定缺失变量默认值

如果一个变量不存在或者null,就要报错,使用!指定一个默认值,如果!后面没有设置值,就显示空

        空值:${dept!}
部门:${dept!'123'}
部门名称:${(dept.name)!'456'}

在这里插入图片描述

内建函数

内建函数语法: 变量 + ? + 函数名

集合长度

users的长度${users?size}

在这里插入图片描述

数据类型

  • 布尔型:类似Java 的 Boolean 类型,不能直接输出,要转为字符串输出
  • 日期型:类似 java 的 Date 类型,不能直接输出,要转为字符串输出
  • 数值型:类似 java 中的 int,float,double 等
  • 三种显示形式:数值型(默认)、货币型、百分比型
  • 字符型:类似java 中的字符串,有很多内置函数
  • sequence :类似java 中的数组,list,set 等集合类型
  • hash:类似 java 中的 Map

布尔值

controller

        //boolean存值model.put("boolValue",true);

ftl:

        

布尔类型

<#-- 数据类型:布尔类型freemarker中布尔类型不能直接输出;如果输出要先转成字符串方式一:?c方式二:?string 或 ?string("true时的文本","false时的文本")--><#-- 直接输出-->${boolValue?c}
${boolValue?string}
<#-- true显示yes,false显示no-->${boolValue?string("yes","no")}

时间类型

controller:

        //日期存值model.put("time",new Date());

ftl:

        

时间类型

<#--数据类型:日期类型在freemarker中日期类型不能直接输出;如果输出要先转成日期型或字符串1. 年月日 ?date2. 时分秒 ?time3. 年月日时分秒 ?datetime4. 指定格式 ?string("自定义格式")y:年 M:月 d:日H:时 m:分 s:秒-->当前时间.now:${.now}
年 月 日
${time?date}
时 分 秒
${time?time}
日期+时间
${time?datetime}
自定义格式化:
${time?string("yyyy年MM月")}
${time?string("yyyy年MM月dd日 HH:mm:ss")}

在这里插入图片描述

数值类型

controller:

        //数值类型model.put("money",1546884512f);model.put("age",10);model.put("score",99.99);

ftl:

        

数值类型

<#--数据类型:数值类型freemarker可以直接输出数值类型1. 转字符串普通字符串 ?c货币型字符串 ?string.currency百分比型字符串 ?string.percent2. 保留浮点型数值指定小数位(#表示一个小数位)?string["0.##"]-->直接输出数值型:${age}
${money}
${score}
数值转字符串输出:${money?c}
数值转成货币类型的字符串输出:${money?string.currency}
数值转百分比类型的字符串输出:${score?string.percent}
浮点型数值保留指定小数位输出 (##表示保留两位小数):${score?string["0.##"]}

在这里插入图片描述

字符串类型

controller

        //字符串类型model.put("name","zhangsan");model.put("city","hulunbeierdacaoyuan");

ftl:

        

字符串类型

<#--数据类型:字符串类型freemarker可以直接输出字符串类型1. 截取字符串(左闭右开) ?substring(start,end)2. 首字母小写输出 ?uncap_first3. 首字母大写输出 ?cap_first4. 字母转小写输出 ?lower_case5. 字母转大写输出 ?upper_case6. 获取字符串长度 ?length7. 是否以指定字符开头(boolean类型) ?starts_with("xx")?string8. 是否以指定字符结尾(boolean类型) ?ends_with("xx")?string9. 获取指定字符的索引 ?index_of("xx")10. 去除字符串前后空格 ?trim11. 替换指定字符串 ?replace("xx","xx")-->直接输出 :${name} - ${city}
${name?string} - ${city?string}
1. 截取字符串 ?substring(start,end) 下标0开始截取5个字符串:${city?substring(0,5)}
2. 首字母小写输出 ?uncap_first :${name?uncap_first}
3. 首字母大写输出 ?cap_first :${city?cap_first}
4. 字母转小写输出 ?lower_case :${name?lower_case}
5. 字母转大写输出 ?upper_case :${name?upper_case}
6. 获取字符串长度 ?length :${name?length}
7. 是否以指定字符开头(boolean类型) ?starts_with("z")?string :${name?starts_with("z")?string}
8. 是否以指定字符结尾(boolean类型) ?ends_with("n")?string :${name?ends_with("n")?string}
9. 获取指定字符的索引,找不到就是-1 ?index_of("g") :${name?index_of("g")}
10. 去除字符串前后空格显示字符串的长度 ?trim :${name?trim?length}
11. 替换指定字符串 ?replace("a","l") :${name?replace("a","l")}

在这里插入图片描述

sequence序列类型

controller:

        //序列类型(list、set、数组)// 数组操作String[] stars = new String[]{"张三","李四","王五","赵六"};model.put("names",stars);// List操作List citys = Arrays.asList("北京","上海","广州","深圳");model.put("citys",citys);// JavaBean集合List userList = new ArrayList<>();userList.add(new User("张三1", 10, "13333333333", "1号胡同"));userList.add(new User("张三2", 20, "23333333333", "2号胡同"));userList.add(new User("张三3", 30, "33333333333", "3号胡同"));model.put("users",userList);

ftl:

        

序列类型

<#--数据类型:序列类型 (数组、List、Set)通过list指令输出序列<#list 序列名 as 元素名>${名称}获取序列长度 ${序列名?size}获取序列元素下标 ${元素名?index}获取第一个元素 ${序列名?first}获取最后一个元素 ${序列名?last}倒序输出 序列名?reverse升序输出 序列名?sort降序输出 序列名?sort?reverse指定字段名排序 序列名?sort_by("字段名")--><#-- 数组操作 --><#list names as name>下标:${name?index} -- 名字:${name}
数组的长度:${names?size}
<#-- 获取第一个元素 -->第一个元素:${names?first}
<#-- 获取最后一个元素 -->最后一个元素:${names?last}

<#-- List操作 --><#list citys as city >${city}
List的size:${citys?size}
<#-- 倒序输出 --><#list citys?reverse as city >${city} -
<#-- 升序输出 --><#list citys?sort as city >${city} -
<#-- 降序输出 --><#list citys?sort?reverse as city >${city} -
<#-- List集合 --><#list users as user>编号:${user_index}  姓名:${user.name}  年龄:${user.age}  
<#-- 按照指定字段名排序 --><#list users?sort_by("age") as user>${user.name} |

在这里插入图片描述

hash类型

controller:

        //hash类型// Map操作Map userMap = new HashMap<>();userMap.put("zhangsan","张三");userMap.put("lisi","李四");userMap.put("wangwu","王五");model.put("userMap",userMap);

ftl:

        

hash类型

<#--数据类型:hash类型key遍历输出<#list hash?keys as key>${key} -- ${hash[key]}value遍历输出<#list hash?values as value>${value}--><#-- key遍历输出 --><#list userMap?keys as key>${key} -- ${userMap[key]}
<#-- value遍历输出 --><#list userMap?values as value>${value} |

在这里插入图片描述

常见指令

assign自定义变量指令

        

assign指令

<#--assign 自定义变量指令语法:<#assign 变量名=值><#assign 变量名=值 变量名=值> (定义多个变量可以用空格隔开)--><#assign str="hello">${str}
<#assign num=1 names=["zhangsan","lisi","wangwu"] >通过逗号分割数组,变成字符串:${num} -- ${names?join(",")}

在这里插入图片描述

json转成对象

assign标签,作用是定义一个变量

实例

list通过下标取值

names和depts都是list

<#list depts as dept>//当前下标${dept_index}//获取当前下标的,dept中的name值${dept.name的值}//获取names中的,跟当前dept一样的下标的name值${names[dept_index].name}

map取值通过list的对象取

map可以使用当前循环的list的对象取值,在这里插入图片描述

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...