FreeMarker简单入门到使用
FreeMarker

freemarker是一个用java开发的模版引擎,百度百科:


常用的java模版还有快要被抛弃的Jsp(熟悉)、Thymeleaf(了解)、Velocity(不知)
freemarker不关心数据的来源,知识根据模版的内容,将数据模型在模版中显示并输出文件;
快速入门难登大雅
SpringMVC在默认情况下是支持freemarker视图格式的,我们创建SpringBoot项目直接上Demo
pom.xml文件如下
<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.yml
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的模版,默认该目录
在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基础
核心指令 —> 数据模型
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";
}
}
List指令--遍历List集合
<!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开始
map指令--遍历Map
输出p1的信息<br/>
姓名:${p1.username}<br/>
年龄:${p1.age}<br/>
遍历输出p1、p2、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表示
if指令--逻辑判断
<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}
assign标签,assign的作用是定义一个变量。
FreeMarker简单入门到使用的更多相关文章
- FreeMarker 快速入门
FreeMarker 快速入门 FreeMarker是一个很值得去学习的模版引擎.它是基于模板文件生成其他文本的通用工具.本章内容通过如何使用FreeMarker生成Html web 页面 和 代码自 ...
- 用IntelliJ IDEA创建Gradle项目简单入门
Gradle和Maven一样,是Java用得最多的构建工具之一,在Maven之前,解决jar包引用的问题真是令人抓狂,有了Maven后日子就好过起来了,而现在又有了Gradle,Maven有的功能它都 ...
- [原创]MYSQL的简单入门
MYSQL简单入门: 查询库名称:show databases; information_schema mysql test 2:创建库 create database 库名 DEFAULT CHAR ...
- Okio 1.9简单入门
Okio 1.9简单入门 Okio库是由square公司开发的,补充了java.io和java.nio的不足,更加方便,快速的访问.存储和处理你的数据.而OkHttp的底层也使用该库作为支持. 该库极 ...
- emacs最简单入门,只要10分钟
macs最简单入门,只要10分钟 windwiny @2013 无聊的时候又看到鼓吹emacs的文章,以前也有几次想尝试,结果都是玩不到10分钟就退出删除了. 这次硬着头皮,打开几篇文章都看完 ...
- 【java开发系列】—— spring简单入门示例
1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...
- Docker 简单入门
Docker 简单入门 http://blog.csdn.net/samxx8/article/details/38946737
- Springmvc整合tiles框架简单入门示例(maven)
Springmvc整合tiles框架简单入门示例(maven) 本教程基于Springmvc,spring mvc和maven怎么弄就不具体说了,这边就只简单说tiles框架的整合. 先贴上源码(免积 ...
- git简单入门
git简单入门 标签(空格分隔): git git是作为程序员必备的技能.在这里就不去介绍版本控制和git产生的历史了. 首先看看常用的git命令: git init git add git comm ...
随机推荐
- Java基本数据类型的类型转换规则
基本类型转换分为自动转换和强制转换. 自动转换规则:容量小的数据类型可以自动转换成容量大的数据类型,也可 以说低级自动向高级转换.这儿的容量指的不是字节数,而是指类型表述的范围. 强制转换规则:高级变 ...
- 基于React Native的跨三端应用架构实践
作者|陈子涵 编辑|覃云 “一次编写, 到处运行”(Write once, run anywhere ) 是很多前端团队孜孜以求的目标.实现这个目标,不但能以最快的速度,将应用推广到各个渠道,而且还能 ...
- LayUI最近遇到的问题以及处理
layui是我最近才接触的..也是新项目中用到的后台前端框架..与easyui有些类似..在这段时间的使用中,经常会碰到大大小小的问题.. 1.选显卡切换又是加载数据表格.分页条不显示 2.layui ...
- 什么是平衡树B-Tree?【转】
转载自:https://www.cnblogs.com/dongguacai/p/7239599.html#commentform B-Tree就是我们常说的B树,一定不要读成B减树,否则就很丢人了. ...
- Vue学习笔记【14】——自定义指令
1.自定义全局和局部(私有)自定义指令 // 自定义全局指令 v-focus,为绑定的元素自动获取焦点: Vue.directive('focus', { inserted: function ...
- sql 性能优化 索引碎片
1.索引 简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包 ...
- redis 配置文件aof配置
redis 配置文件aof配置: bind 127.0.0.1 port 6379 daemonize yes dbfilename dump.rdb dir /new_renpeng/redis/ ...
- HTML中<frameset>标签不显示的问题
啥都不说,先上代码 <html> <head> <title>index</title> <meta content = 'text/html'; ...
- Redis数据结构之快速列表-quicklist
链表 在Redis的早期版本中,存储list列表结构时,如果元素少则使用压缩列表ziplist,否则使用双向链表linkedlist // 链表节点 struct listNode<T> ...
- <随便写>软件设计遵循的基本原则
1.高内聚,低耦合 所谓高内聚,是指一个软件模块内各个元素彼此结合的紧密程度要高,即一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则. 所谓低耦合,是指一个软件系统内不同 ...
