Freemarker模板引擎技术
①概念
FreeMarker是一款模板引擎:即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。需要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,主要用于如何展现数据, 而在模板之外注意于要展示什么数据。
②工作原理
所有的模板视图技术的工作原理基本类似,也就意味着FreeMarker和JSP基本差不多。模板文件和数据模型是模板视图技术用来生成HTML页面所必须的组成部分。
数据模型(Java) + 模板文件(.ftl .jsp文件)= 输出(HTML,XML,源码文件)
JSP在Web系统中弥补了Servlet生成HTML页面的不足,但只能应用于Web系统,生成HTML页面。而FreeMarker不仅仅应用于Web系统,也可以应用于Java系统,还能生成Java, XML等文件,所以应用面更广。使用时,需要在项目pom.xml文件中增加依赖关系。
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.19</version> </dependency>
用在SpringMVC中时需要加入对应的视图解析器
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <!-- <property name="templateLoaderPath" value="/WEB-INF/ftl/" /> --> <property name="templateLoaderPaths"> <list> <value>/WEB-INF/ftl/</value> <value>classpath:/ftl/</value> </list> </property> <property name="freemarkerSettings"> <props> <prop key="defaultEncoding">UTF-8</prop> <!-- FreeMarker默认每隔5秒检查模板是否被更新,如果已经更新了,就会重新加载并分析模板。 但经常检查模板是否更新可能比较耗时。如果你的应用运行在生产模式下,而且你预期模板不会经常更新, 则可以将更新的延迟时间延长至一个小时或者更久。 可以通过为freemarkerSettings属性设置template_update_delay达到这一目的,0 表示每次都重新加载 --> <prop key="template_update_delay">0</prop> <prop key="default_encoding">UTF-8</prop> <prop key="number_format">0.##########</prop> <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> <prop key="classic_compatible">true</prop> <prop key="template_exception_handler">ignore</prop> </props> </property> </bean> <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" p:prefix="/" p:suffix=".ftl"> <property name="cache" value="false" /> <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> <property name="contentType" value="text/html;charset=UTF-8"></property> <property name="exposeRequestAttributes" value="true" /> <property name="exposeSessionAttributes" value="true" /> <property name="exposeSpringMacroHelpers" value="true" /> <property name="requestContextAttribute" value="base"></property> <property name="order" value="0"></property> </bean>
③基本语法
${...}
FreeMarker将会输出真实的值来替换大括号内的表达式,这样的表达式被称为interpolation(插值)。
<#-- 注释内容 -->
注释和HTML的注释也很相似,但是它们使用<#-- and -->来标识。不像HTML注释那样,FTL注释不会出现在输出中(不出现在访问者的页面中),因为FreeMarker会跳过它们。
<#if condition> ... <#elseif condition2> ... <#elseif condition3> ... <#else> ... </#if>
FTL标签和HTML标签有一些相似之处,但是它们是FreeMarker的指令,是不会在输出中打印的。这些标签的名字以#开头。(用户自定义的FTL标签则需要使用@来代替#)
④例子
bean.ftl文件
package ${packageName}.bean; public class ${className} { }
Java代码
// 创建Freemarker对象的配置对象 Configuration cfg = new Configuration(); // 设定默认的位置(路径) cfg.setDirectoryForTemplateLoading(new File("")); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); // 数据 Map paramMap = new HashMap(); String className = "User"; paramMap.put("packageName", "com.atguigu.crowdfunding"); paramMap.put("className", className); Template t = cfg.getTemplate("bean.ftl"); // 组合生成 Writer out = new OutputStreamWriter(new FileOutputStream(new File("User.java")), "UTF-8"); // 执行 t.process(paramMap, out);
⑤常用语法
<#if condition> ... <#elseif condition2> ... <#elseif condition3> ... <#else> ... </#if>
[2]循环
<#list users as user> ${user.name},${user_index} </#list>
[3]包含
<#include "xxxx.ftl">
[4]表达式
表达式 | 说明 |
${Request.member.name} | 从Request域读取数据 |
${Session.member.name} | 从Session域读取数据 |
${Application.member.name} | 从Application域读取数据 |
${RequestParameters['id']} | 读取请求参数 |
${book.name?if_exists } | 用于判断如果存在,就输出这个值 |
${book.name?default(‘xxx’)} | 默认值xxx |
${book.name!"xxx"} | 默认值xxx |
${book.date?string('yyyy-MM-dd')} | 日期格式 |
s?html | 对字符串进行HTML编码 |
s?cap_first | 使字符串第一个字母大写 |
s?lower_case | 将字符串转换成小写 |
s?trim | 去掉字符串前后的空白字符 |
s?size | 获得序列中元素的数目 |
SpringBoot中使用FreeMarker
①依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
②增加相关配置
spring.freemarker.allow-request-override=false spring.freemarker.allow-session-override=false spring.freemarker.cache=true spring.freemarker.charset=UTF-8 spring.freemarker.check-template-location=true spring.freemarker.content-type=text/html spring.freemarker.enabled=true spring.freemarker.expose-request-attributes=false spring.freemarker.expose-session-attributes=false spring.freemarker.expose-spring-macro-helpers=true spring.freemarker.prefer-file-system-access=false spring.freemarker.suffix=.ftl spring.freemarker.template-loader-path=classpath:/templates/ spring.freemarker.settings.template_update_delay=0 spring.freemarker.settings.default_encoding=UTF-8 spring.freemarker.settings.classic_compatible=true spring.freemarker.order=1
其中最重要的是spring.freemarker.suffix和spring.freemarker.template-loader-path,其他配置项可以使用默认值。
@RequestMapping("/testftl") public String testFtl(Model model) { model.addAttribute("message", "good news!!!"); return "target"; }
freemarker集成maven的简单的应用
之前做过的分布式项目中就有用到freemarker
项目在我的github上
也可以在百度云上下载
注意:导入项目后需要相应的修改,这里分享我的maven仓库防止导入项目全部报红。