SpringBoot整合FreeMarker使用笔记

前言

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

在这里插入图片描述

使用

导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

配置文件 - yml格式

spring:
  freemarker:
    #指定HttpServletRequest的属性是否可以覆盖controller的model的同名项
    allow-request-override: false
    #req访问request
    request-context-attribute: req
    #后缀名freemarker默认后缀为.ftl,当然你也可以改成自己习惯的.html
    suffix: .html
    #设置响应的内容类型
    content-type: text/html;charset=utf-8
    #是否允许mvc使用freemarker
    enabled: true
    #是否开启template caching
    cache: false
    #设定模板的加载路径,多个以逗号分隔,默认: [“classpath:/templates/”]
    template-loader-path: classpath:/templates/
    #设定Template的编码
    charset: UTF-8

模板语法及代码示例

模板语法

  • 简单取值

${paramName?if_exists}       // 变量存在,输出该变量,否则不输出
${paramName!}           // 变量存在,输出该变量,否则不输出
${paramName?default(“xxx”)} // 变量不存在,取默认值xxx
${paramName!“xxx”}        // 变量不存在,取默认值xxx

  • 内置函数

${“123456”?html}   // 对字符串进行HTML编码,对html中特殊字符进行转义
${“str”?cap_first}    // 使字符串第一个字母大写
${“Str”?lower_case} // 将字符串转换成小写
${“Str”?upper_case} // 将字符串转换成大写
${“str”?trim} // 去掉字符串前后的空白字符

  • 字符串拼接

$ { “你好$ {emp.name!}”} //输出你好+变量名
$ {“hello”+ emp.name!} //使用+号来连接,输出你好+变量名

  • 截取字符串

<#assign str =“abcdefghijklmn”/>
//方法1
$ {str?substring(0,4)} //输出abcd
//方法2
$ { str [ 0 ] } $ {str [4]} //结果是ae
$ {str [1…4]} //结果是bcde
//返回指定字符的索引
$ {str?index_of(“n”)}

  • 日期转换

$ {emp.date?string(‘yyyy -MM-dd’)} //日期格式

  • 输出数字

$ {emp.name?string.number} //输出20
$ {emp.name?string.currency} //¥20.00
$ {emp.name?string.percent} // 20%
$ {1.222?int} //将小数转为int,输出1
<#setting number_format =“percent”/> //设置数字默认输出方式(‘percent’,百分比)
<#assign answer = 42 /> //声明变量回答42
#{answer} //输出4,200%
$ {answer?string} //输出4,200%
$ {answer?string.number} //输出42
$ {answer?string.currency} //输出¥42.00
$ {answer?string.percent} //输出4,200%
#{answer} //输出42
数字格式化插值可采用#{expr; format}形式来格式化数字,其中格式可以是:
mX:小数部分最小X位
MX:小数部分最大X位
如下面的例子:
<#assign x = 2.582 /> <#assign y = 4 />
# {x; M2} //输出2.58
# {y; M2} //输出4
# {x; m2} //输出2.58
#{Y; m2} //输出4.0
# {x; m1M2} //输出2.58
# {x; m1M2} //输出4.0

  • 声明变量

<#assign foo = false /> //声明变量,插入布尔值进行显示,注意不要用引号
$ {foo?string(“yes”,“no”)} //当为真时输出“yes”,否则输出“no”
<#assign name = value>
<#assign name1 = value1 name2 = value2 … nameN = valueN>
<#assign same as above… in namespacehash>
<#assign name>
capture this
</#assign>
<#assign name in namespacehash>
capture this
</#assign>

  • 比较运算符

表达式中支持的比较运算符符如下几个:
=或==:判断两个值是否相等。
!=:判断两个值是否不等。
或gt:判断左边值是否大于右边值>
<=或lte:判断左边值是否小于等于右边值

  • 算术运算符

FreeMarker表达式中完全支持算术运算,
FreeMarker支持的算术运算符包括:+, - ,*,/,%
注意:
(1)运算符两边必须是数字
(2)使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,
如:$ {3 +“5”},结果是:35

  • 逻辑运算符

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

  • 运算符优先级如下(由高到低排列)

①,一元运算符:!
②,内建函数:
③,乘除法:*,/,%
④,加减法: - ,+
⑤,比较:>,<,> =,<=(lt,lte,gt,gte)
⑥,相等:==,=, !=
⑦,逻辑与:&&
⑧,逻辑或:||
⑨,数字范围:… 实际上,我们在开发过程中应该使用括号来严格区分,这样的可读性好,出错少

  • if判断

<#if condition>

<#elseif condition2>

<#elseif condition3>

<#else>

</#if>
if 空值判断
// 当 photoList 不为空时
<#if photoList??>…</#if>
值得注意的是,${…}只能用于文本部分,不能用于表达式,下面的代码是错误的:
<#if KaTeX parse error: Expected 'EOF', got '#' at position 15: {isBig}>Wow!</#̲if> <#if "{isBig}">Wow!</#if>
// 正确写法
<#if isBig>Wow!</#if>

  • switch判断

<#switch value>
<#case refValue1>

<#break>
<#case refValue2>

<#break>
<#case refValueN>

<#break>
<#default>

</#switch>

  • 循环遍历

// 遍历集合:
<#list empList! as emp>
${emp.name!}
</#list>
// 可以这样遍历集合:
<#list 0…(empList!?size-1) as i>
${empList[i].name!}
</#list>
// 与jstl循环类似,也可以访问循环的状态。
empList?size    // 取集合的长度
emp_index:     // int类型,当前对象的索引值
emp_has_next: // boolean类型,是否存在下一个对象
// 使用<#break>跳出循环
<#if emp_index = 0><#break></#if>
// 集合长度判断
<#if empList?size != 0></#if> // 判断=的时候,注意只要一个=符号,而不是==
<#assign l=0…100/> // 定义一个int区间的0~100的集合,数字范围也支持反递增,如100…2
<#list 0…100 as i>   // 等效于java for(int i=0; i <= 100; i++)
${i}
</#list>
// 截取子集合:
empList[3…5] //返回empList集合的子集合,子集合中的元素是empList集合中的第4-6个元素
// 创建集合:
<#list [“星期一”, “星期二”, “星期三”, “星期四”, “星期五”, “星期六”, “星期天”] as x>
// 集合连接运算,将两个集合连接成一个新的集合
<#list [“星期一”,“星期二”,“星期三”] + [“星期四”,“星期五”,“星期六”,“星期天”] as x>
// 除此之外,集合元素也可以是表达式,例子如下:
[2 + 2, [1, 2, 3, 4], “whatnot”]
// seq_contains:判断序列中的元素是否存在
<#assign x = [“red”, 16, “blue”, “cyan”]>
${x?seq_contains(“blue”)?string(“yes”, “no”)} // yes
${x?seq_contains(“yellow”)?string(“yes”, “no”)} // no
${x?seq_contains(16)?string(“yes”, “no”)} // yes
${x?seq_contains(“16”)?string(“yes”, “no”)} // no
// seq_index_of:第一次出现的索引
<#assign x = [“red”, 16, “blue”, “cyan”, “blue”]>
KaTeX parse error: Expected 'EOF', got '#' at position 51: …ort_by:排序(升序) <#̲list movies?sor…{moive.url}“>KaTeX parse error: Expected 'EOF', got '#' at position 20: …ve.name}</a> </#̲list> //要是排序,则用…{movie.url}”>KaTeX parse error: Expected 'EOF', got '#' at position 20: …ie.name}</a> </#̲list> // 这是按元素的…{movie.url}“>KaTeX parse error: Expected 'EOF', got '#' at position 20: …ie.name}</a> </#̲list> //这个是按lis…{movie.url}”>${movie.name}
</#list>

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>${titleName}</title>
</head>
<body>
  <p>
    <h1>${welcome!"Hello World"}</h1>
  </p>
</body>
</html>
@Controller
@RequestMapping("free")
public class FreeMarkerController {
    @RequestMapping("baseTemplate")
    public String baseTemplate(Model model){
        model.addAttribute("titleName","FreeMarker示例");
        model.addAttribute("welcome","day day up");
        return "index";
    }
}

生成静态页面

代码示例

public void createStaticTemplate() {
        //模板名称
        String templateName = "index.html";
        //获取模板取值
        Map<String, Object> map = new HashMap<>(16);
        map.put("titleName","FreeMarker");
        map.put("welcome","day day up");
        try {
            //FreeMarkerConfigurer直接注入使用 根据模板名称去目录下获取对应模板
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, StandardCharsets.UTF_8.name());
            //获取HOME路径
            String home = System.getenv("HOME");
            //输出路径
            String targetFile = home + File.separator + "tmp" + File.separator + RandomStringUtils.randomNumeric(4) + "_" + templateName;
            try (FileWriter writer = new FileWriter(targetFile)) {
                template.process(map, writer);
            }
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

获取模板内容

//templateName 模板名称
//map 模板取值
	@Override
    public String getTemplateContext(String templateName, Map<String, Object> map){
        try {
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateName, StandardCharsets.UTF_8.name());
            return FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        } catch (IOException | TemplateException e) {
            String msg = "创建模板并获取内容时抛出异常:" + e.getMessage();
            log.error(msg, e);
            throw new BusinessException(msg, e);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值