freemarker是一个用java开发的模版引擎,百度百科:html
经常使用的java模版还有快要被抛弃的Jsp(熟悉)、Thymeleaf(了解)、Velocity(不知)java
freemarker不关心数据的来源,知识根据模版的内容,将数据模型在模版中显示并输出文件;web
SpringMVC在默认状况下是支持freemarker视图格式的,咱们建立SpringBoot项目直接上Demospring
pom.xml文件以下apache
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
日志安排:lomback-spring.xml缓存
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--定义日志文件的存储地址,使用绝对路径--> <property name="LOG_HOME" value="E:\logs"/> <!-- Console 输出设置 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>utf8</charset> </encoder> </appender> <!-- 按照天天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 异步输出 --> <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <!-- 不丢失日志.默认的,若是队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> <discardingThreshold>0</discardingThreshold> <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> <queueSize>512</queueSize> <!-- 添加附加的appender,最多只能添加一个 --> <appender-ref ref="FILE"/> </appender> <logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE"/> </logger> <logger name="org.springframework.boot" level="DEBUG"/> <root level="info"> <!--<appender-ref ref="ASYNC"/>--> <appender-ref ref="FILE"/> <appender-ref ref="CONSOLE"/> </root> </configuration>
配置文件:application.ymlapp
server: port: 8888 spring: application: name: test-freemarker freemarker: cache: false #关闭模版缓存 settings: template_update_delay: 0 #检查模版更新延迟时间,0表示当即检查,若是大于0会有延迟,不利于测试唷 logging.level.org.springframework.boot.autoconfigure: ERROR #后来加上的,专治SpringBoot项目起来不少日志的状况
咱们建立一个模型类,用于测试:待用异步
@Data @ToString public class People { private String username; private int age; private Float money; private List<People> friends; //他的朋友们 private People bestPeople; //他最好的朋友 }
建立模版:函数
在resource目录下建立templates目录,用来存放freemarker的模版,默认该目录spring-boot
在templates中建立 test1.ftl内容以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FreemarkerTest1</title> </head> <body> 欢迎您:${name} ! </body> </html>
编写Controller:
@Controller @RequestMapping("/freemarker") public class FreemarkerController { //待用 @Autowired private RestTemplate restTemplate; @RequestMapping("/test") public String freemarker(Map<String,Object> map){ map.put("name", "警察叔叔"); return "test1"; } }
编写启动类:
@SpringBootApplication public class FreemarkerApplication { public static void main(String[] args) { SpringApplication.run(FreemarkerApplication.class); } //待用 @Bean public RestTemplate instance(){ return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); } }
等项目起来了,咱们能够访问测试:http://localhost:8888/freemarker/test
有没有一种Jsp的味道在里面?反正我感受是查询的意思,后面的语法有些改变
Freemarker静态化依赖与数据模型和模版,下面定义数据模型
在上面的那个小Demo中,咱们的数据模型也有使用,至于形参Map即为Freemarker静态化所须要的数据模型,在Map中填充数据便可
@Controller @RequestMapping("/freemarker") public class FreemarkerController { @Autowired private RestTemplate restTemplate; @RequestMapping("/test") public String freemarker(Map<String,Object> map){ map.put("name", "警察叔叔"); //三我的的信息 People p1 = new People("Ninja400",10,12580.01f,null,null); People p2 = new People("Ninja650",20,12580.01f,null,null); People p3 = new People("Ninja250",30,12580.01f,null,null); //p1有两个好友 分别是p2 p3 List<People> friends = new ArrayList<>(); friends.add(p2); friends.add(p3); p1.setFriends(friends); //向Map中放入个人朋友们List map.put("friends", friends); //三我的的信息采集 HashMap<String,People> peopleMap = new HashMap<>(); peopleMap.put("p1", p1); peopleMap.put("p2", p2); peopleMap.put("p3", p3); //所有People的信息和 个人信息 map.put("peopleMap",peopleMap); map.put("p1", p1); return "test1"; } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FreemarkerTest1</title> </head> <body> 欢迎您:${name}!下面是个人同伙们! <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list friends as friend> <tr> <td>${friend_index + 1}</td> <td>${friend.username}</td> <td>${friend.age}</td> <td>${friend.money}</td> </tr> </#list> </table> </body> </html>
<#list friends as friend> 使用list指令遍历friends集合并将得到的每一个值赋值给friend
_index:获得循环的下标,从0开始
输出p1的信息<br/> 姓名:${p1.username}<br/> 年龄:${p1.age}<br/> 遍历输出p一、p二、p3的信息<br/> <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list peopleMap?keys as k> <tr> <td>${k_index + 1}</td> <td>${peopleMap[k].username}</td> <td>${peopleMap[k].age}</td> <td >${peopleMap[k].money}</td> </tr> </#list> </table>
${p1.username} :若是参数是在咱们的形参中,当存如后可经过Map的主键这样获取
<#list peopleMap?keys as k> 遍历这个Map,指定主键用K表示
<table>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
<td>钱包</td>
</tr>
<#list friends as friend>
<tr>
<td>${friend_index + 1}</td>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
<td>${friend.age}</td>
<td>${friend.money}</td>
</tr>
</#list>
</table>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
若是遍历获得的对象的username属性是 Ninja250,该行的背景色显示为蓝色
FreeMarker支持的算术运算符包括:+、 - 、 * 、 / 、 % 2
逻辑运算符有以下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能做用于布尔值,不然将产生错误
比较运算符 表达式中支持的比较运算符有以下几个:
1 =或者==:判断两个值是否相等.
2 !=:判断两个值是否不等.
3 >或者gt:判断左边值是否大于右边值
4 >=或者gte:判断左边值是否大于等于右边值
5 <或者lt:判断左边值是否小于右边值
6 <=或者lte:判断左边值是否小于等于右边值
注意:
=和!=能够用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,不然会产生错误,并且 FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符能够做用于数字和日期,但不能做用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,由于 FreeMarker会把>解释成FTL标签的结束字符,固然,也可使用括号来避免这种状况,如:<#if (x>y)>
判断某变量是否存在使用: xx??,以下,
<#if friends??>:为了防止friends为空报错能够加一个预判断,返回boolean
<#if friends??>
<#list friends as friend>
<tr>
<td>${friend_index + 1}</td>
<td <#if friend.username == 'Ninja250'> style="background: dodgerblue" </#if>>${friend.username}</td>
<td>${friend.age!""}</td>
<td>${friend.money}</td>
</tr>
</#list>
</#if>
<td>${friend.age!""}</td> :当这个对象的age属性为空时,使用缺失变量默认为空字符串 “”
使用!必定要指定一个默认值,当咱们的属性存在多层嵌套时,能够用括号括起来,好比:
${(p1.bestPeople.name)!''} :若是p1最好的朋友的name这个属性为空,用空字符串表示
内建函数语法格式:变量 + ? + 函数名称
某个集合的大小:
我有${friends?size}个同伙!
日期格式化:
map.put("now", new Date());
显示年月日: ${now?date} <td/> 显示时分秒:${now?time} <td/> 显示日期+时间:${now?datetime} <td/> 自定义格式化: ${now?string("yyyy年MM月")}
内建函数
map.put("point",123456789);
当point是数字型,使用${point}会显示这个数字的值,默认每隔三位使用逗号分隔。 若是不想显示为每三位分隔的数字,可使用c函数将数字型转成字符串输出
咱们的座机号码是:<br> ${point} <br> ${point?c} <br>
将Json字符串撰文对象
<#assign text="{'name':'挽起袖子的年轻人','address':'四川省成都市成华区动物园单身狗圈养处'}" /> <#assign data=text?eval /> 我是谁:${data.name} 地址:${data.address}