- freemaker完整使用教程可以参考官方中文文档或其他文档。
- 这里只讲SpringBoot框架下如何快速搭建。
第一步: 在pom.xml里面配置freemakerjar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
第二步: 在application.properties 配置freemaker引用文件路径,格式等
# freemaker
spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.suffix=.ftl
spring.freemarker.templateEncoding=UTF-8
spring.freemarker.templateLoaderPath=/WEB-INF/
spring.freemarker.expose-spring-macro-helpers=false
spring.freemarker.request-context-attribute=rq
第三步: 在windows>Proferences >Content-types>下面, 找到text>jsp,添加一个新的规则 *.ftl, 这样当eclipse编译器检测到有.ftl格式,即freemaker格式的文件时,就会使用jsp的格式校验。 同理, 在html的格式校验规则里面加 *.ftl也可以。
第四步: 当我们在ftl文件中引用js/css或者调用方法的时候,项目根目录地址就是${rq.contextPath}, 其中 “rq” 使我们在application.properties里面配置的
spring.freemarker.request-context-attribute=rq
controller(后台写法不受影响):
package com.exp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping("/list")
public String test(){
return "test/list";
}
}
ftl:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="${rq.contextPath}/bootstrap/css/bootstrap.css" >
<!-- jQuery -->
<script src="${rq.contextPath}/jquery/jquery.js" ></script>
<!-- bootstrap -->
<script src="${rq.contextPath}/bootstrap/js/bootstrap.js" ></script>
<script>
$(function(){
$("#test").click(function(){
alert("你好");
})
})
</script>
</head>
<body>
<div class="container">
你好,我是flt
<button id="test" class="btn btn-primary">点击</button>
</div>
</body>
</html>
运行结果:
=======================================
- 例子
- 数据类型基本操作:
java:
- 数据类型基本操作:
// 列表
List<Student> lst=studentService.list();
model.addAttribute("resultList",lst);
// 布尔
boolean booleantest=false;
model.addAttribute("booleantest",booleantest);
// java date 需要前台判断转换日期类型
Date javaDate=new Date();
model.addAttribute("javaDate",javaDate);
// sql date 可以显示
Date sqlDate=new java.sql.Date(new Date().getTime());
model.addAttribute("sqlDate",sqlDate);
// 空数据
String nullDate = null;
model.addAttribute("nullDate",nullDate);
//list对象
Student st=new Student();
st.setSname("宫甜甜");
st.setClassNum("<font color='red'>html</font>");
model.addAttribute("userObj",st);
//map 对象
Map<String,String> map=new HashMap<String,String>();
map.put("java", "你好java");
map.put("html", "你好html");
map.put("js", "你好js");
model.addAttribute("mapTest",map);
return "test/list";
ftl:
<div class="group_c">
<h2>1.freemaker 练习- list</h2>
<ul>
<#list resultList as item>
<li>${item.sname!},性别:${item.ssex}</li> </#list>
</ul>
</div>
<div class="group_c">
<h2>2.freemaker 练习- 集合map</h2>
<ul>
<#list mapTest?keys as item>
<li>${item}---${mapTest[item]}</li>
</#list>
</ul>
</div>
<div class="group_c">
<h2>3.freemaker 练习- 布尔值</h2>
<p>${booleantest?string('是','否')}</p>
</div>
<div class="group_c">
<h2>4.freemaker 练习- java日期</h2>
<p>java date需要转换:${javaDate?string('yyyy-MM-dd')}</p>
<p>sql date直接显示:${sqlDate}</p>
</div>
<div class="group_c">
<h2>5.freemaker 练习- 空指针异常</h2>
<p>${nullDate!'我是默认值'}</p>
</div>
<div class="group_c">
<h2>6.freemaker 练习- 赋值</h2>
<p><#assign a=100 /> 变量a的值为${a},变量a+5等于${a+5}</p>
</div>
<div class="group_c">
<h2>7.freemaker 练习- 对象取值</h2>
<p>${(userObj.sname)!"没有找到user对象" }</p>
<p>${(userObj.classNum)!"没有找到user对象" }</p>
<p>${(userObj.classNum)!?html}</p>
</div>
运行结果:
- 逻辑 if的使用
ftl:
<div class="group_c">
<h2>8.freemaker 练习- 逻辑if(可以使用|| && !多条件判断)</h2>
<!-- 定义一个变量 b -->
<#assign b=29/>
<!-- 判断变量是否存在 ?? 等同于 ?exists -->
<#if b??>
<p>只有存在变量b,才会执行这里面的语句</p>
<#else>
<p>没有找到变量b</p>
</#if>
<!-- if else -->
<#if b==99>
<p>变量是99</p>
<#else>
<p>变量不是99</p>
</#if>
<!-- if elseif else -->
<#if b >99>
<p>变量b大于99</p>
<#elseif b==99>
<p>变量b等于99</p>
<#else>
<p>变量b小于99</p>
</#if>
</div>
运行结果:
- switch的使用
ftl:
<div class="group_c">
<h2>9.freemaker 练习- Switch</h2>
<!-- 定义一个变量vars -->
<#assign days="星期天"/>
<#switch days>
<#case "星期一">
<p>今天是星期一,上班</p>
<#break>
<#case "星期二">
<p>今天是星期二,上班</p>
<#break>
<#case "星期三">
<p>今天是星期三,上班</p>
<#break>
<#case "星期四">
<p>今天是星期4,上班</p>
<#break>
<#case "星期五">
<p>今天是星期5,上班</p>
<#break>
<#case "星期六">
<#case "星期天">
<p>周末了。休息吧</p>
<#break>
<#default>
<p>很抱歉,可能输入有误,查询不到...</p>
</#switch>
</div>
运行结果:
- 字符串相关
ftl:
<div class="group_c">
<h2>10.freemaker 练习- 字符串相关 连接 ,截取,长度等</h2>
<#assign a='hello'>
<#assign b='world'>
<p>连接: ${a+b}</p>
<p>截取: ${(a+b)?substring(5,8)}</p>
<p>长度: ${(a+b)?length}</p>
<p>大写: ${(a+b)?upper_case}</p>
<p>小写: ${(a+b)?lower_case}</p>
<p>字母第一次出现的位置index_of: ${(a+b)?index_of('l')}</p>
<p>字母最后一次出现的位置index_of: ${(a+b)?last_index_of('l')}</p>
<p>替换 replace: ${(a+b)?replace('world','tiantian')}</p>
</div>
运行结果:
- list常用指令 排序,降序, 长度,指定下标等
ftl:
<div class="group_c">
<h2>11.freemaker 练习- list常用指令</h2>
<!-- 定义一个整数数组 -->
<#assign myList=[1,22,13,11,35]>
<p>未排序</p>
<#list myList as item>
<p>${item_index+1}----- ${item}</p>
</#list>
<p>排序(升序)</p>
<#list myList?sort as item>
<p>${item_index+1}----- ${item}</p>
</#list>
<p>排序(降序)</p>
<#list myList?sort?reverse as item>
<p>${item_index+1}----- ${item}</p>
</#list>
<p>list的长度: ${myList?size}</p>
<p>指定list的下标: ${myList[2]}</p>
</div>
运行结果:
- 内建函数(有很多, 参考官方文档)
ftl:
<div class="group_c">
<h2>12.freemaker 练习- 内建函数</h2>
<p>===字符串内建函数-split</p>
<#assign sp="gg,oo,nn,gg" >
<#list sp?split(",") as item>
<p>${item}</p>
</#list>
<p>===数字类型内建函数-四舍五入, 取整</p>
<#assign pai=3.1415926>
<p>四舍五入指定小数位数:${pai?string("0.##")}</p>
<p>四舍五入取整:${pai?round}</p>
<p>===list内建函数,分块</p>
<#assign mylist=[1,2,3,4,5,6,7,8,9,10,11,12]>
<p>每组三个,一共:${mylist?chunk(4)?size}组, 把最后一组打印出来</p>
<#list mylist?chunk(4)?last as item>
<p>${item}</p>
</#list>
</div>
- 宏macro(代码片段封装)
ftl:
<div class="macro">
<h2>==宏macro基本结构: 调用<@macro_name param /></h2>
<!--1.定义一个无参数的test 宏 -->
<#macro test1>
<p>我是test1宏</p>
<p>我是test1宏里的内容</p>
<hr>
</#macro>
<@test1 /><@test1 />
<!--2.定义一个有参数的test2 宏 -->
<#macro test2 param1 param2>
<p>我是test2,参数1:${param1} 参数2:${param2}</p>
</#macro>
<@test2 param1='hello' param2='world'/>
<@test2 param1='你好' param2='中国'/>
<!--3.定义一个有参数且有默认值的test3 宏 -->
<#macro test3 param1="默认值" param2="默认值">
<p>我是test3,参数1:${param1} 参数2:${param2}</p>
<hr>
</#macro>
<@test3 param1="hello" />
<!--4.定义一个有参数且有多个参数的test4 宏 多个参数是map对象用param_name...来表示 -->
<#macro test4 param1 param2 parmas...>
<p>我是test4,参数1:${param1} 参数2:${param2}</p>
<p>多参数:${parmas['a'] }</p>
<p>多参数:${parmas['b'] }</p>
<p>多参数:${parmas['c'] }</p>
<hr>
</#macro>
<@test4 param1="hello" param2="world" a="java" b="nodejs" c="php" />
<!--5.定义一个带有嵌套指令nested 的宏 -->
<#macro test5 param1>
<p>我是test5宏,参数1: ${param1}</p>
<#nested param1,"我是nested">
</#macro>
<@test5 param1="参数1111"; a1,a2>
<p>ccccccc${a1},${a2}</p>
</@test5>
<@test5 param1="参数11111111"; a1>
<p>ccccccc${a1}</p>
</@test5>
</div>
运行结果:
- 函数function
ftl:
<h2>==函数</h2>
<!--function 函数 -->
<#function doAdd p1 p2>
<#return p1+p2>
</#function>
<p>调用</p>
<p>返回结果:${doAdd(100,50) }</p>
<p>返回结果:${doAdd(20,30) }</p>
运行结果:
freemaker官方中文文档链接