一、FreeMaker介绍

FreeMarker是一款免费的Java模板引擎,是一种基于模板和数据生成文本(HMLT、电子邮件、配置文件、源代码等)的工具,它不是面向最终用户的,而是一款程序员使用的组件。

FreeMarker最初设计是用来在MVC模式的Web开发中生成HTML页面的,所以没有绑定Servlet或任意Web相关的东西上,所以它可以运行在非Web应用环境中。

发展史

FreeMarker第一版在1999年未就发布了,2002年初使用JavaCC(Java Compiler Compiler是一个用Java开发的语法分析生成器)重写了FreeMarker的核心代码,2015年FreeMarker代码迁移到了Apache下。

GitHub地址:https://github.com/apache/freemarker

工作原理

FreeMarker模板存储在服务器上,当有用户访问的时候,FreeMarker会查询出相应的数据,替换模板中的标签,生成最终的HTML返回给用户,如下图:

二、FreeMarker基础使用

基础使用分为3部分,这3部分组成了FreeMarker:

  • 指令

  • 表达式

指令是FreeMarker用来识别转换的特殊标签,表达式是标签里具体的语法实现,其他部分是一些不好分类的模板。

2.1 指令

使用FTL(freemarker template language)标签来调用指令。

指令速览:

  • assign

  • attempt, recover

  • compress

  • escape, noescape

  • flush

  • ftl

  • function, return

  • global

  • if, else, elseif

  • import

  • include

  • list, else, items, sep, break

  • local

  • macro, nested, return

  • noparse

  • nt

  • setting

  • stop

  • switch, case, default, break

  • t, lt, rt

  • visit, recurse, fallback

  • 用户自定义标签

下来我们分别来看每个指令对应具体使用。

2.1.1 assign 代码声明

assign 分为变量和代码片段声明两种。

2.1.1.1 变量声明

可以是单变量声明,或多变量声明,下面是多变量声明的示例:

<#assign name="adam" age=18 "sex"="man">${name} - ${age} - ${"sex"}

单个变量的话,只写一个就可以了。

2.1.1.2 代码片段声明
<#assign code>
    <#list ["java","golang"] as c>
        ${c}    </#list></#assign>${code}

其中 ${code} 是用来执行方法的,如果不调用话,代码片段不会执行。

2.1.2 attempt, recover 异常指令

attempt(尝试), recover(恢复)指令类似于程序的try catch,示例如下:

<#attempt>
   i am ${name}   <#recover>
   error name</#attempt>

如果有变量“name”就会正常显示,显示“i am xxx”,如果没有变量就会显示“error name”。

2.1.3 compress 压缩代码移除空白行

<#compress>
  1 2  3   4    5     
  test only   I said, test only</#compress>1 2  3   4    5 test only I said, test only

效果如下:

对空白不敏感的格式,移除空白行还是挺有用的功能。

2.1.4 escape, noescape 转义,不转义

2.1.4.1 escape使用
<#escape x as x?html>
    ${firstName}
    ${lastName}</#escape>

上面的代码,类似于:

${firstName?html}
${lastName?html}

Java代码:

@RequestMapping("/")public ModelAndView index() {
  ModelAndView modelAndView = new ModelAndView("/index");
  modelAndView.addObject("firstName", "<span style='color:red'>firstName</span>");
  modelAndView.addObject("lastName", "lastName");  return modelAndView;
}

最终的效果是:

2.1.4.2 “?html”语法解析

单问号后面跟的是操作函数,类似于Java中的方法名,html属于内建函数的一个,表示字符串会按照HTML标记输出,字符替换规则如下:

  • < 替换为 &lt;

  • > 替换为 &gt;

  • & 替换为 &amp;

  • " 替换为 &quot;

2.1.4.3 noescape使用

HTML代码:

<#escape x as x?html>
    <#noescape>
        ${firstName}    </#noescape>
    ${lastName}</#escape>

Java代码:

@RequestMapping("/")public ModelAndView index() {
  ModelAndView modelAndView = new ModelAndView("/index");
  modelAndView.addObject("firstName", "<span style='color:red'>firstName</span>");
  modelAndView.addObject("lastName", "lastName");  return modelAndView;
}

最终效果:

2.1.5 function, return 方法声明

代码格式:

<#function name param1 param2 ... paramN>
  ...
  <#return returnValue>
  ...
</#function>
  • name 为方法名称

  • param1, param2,paramN 方法传递过来的参数,可以有无限个参数,或者没有任何参数

  • return 方法返回的值,可以出现在function的任何位置和出现任意次数

示例代码如下:

<#function sum x y z>
    <#return x+y+z></#function>${sum(5,5,5)}

注意:function如果没有return是没有意义的,相当于返回null,而function之中信息是不会打印到页面的,示例如下:

<#function wantToPrint>
    这里的信息是显示不了的</#function><#if wantToPrint()??>
    Message:${wantToPrint()}</#if>

“??”用于判断值是否是null,如果为null是不执行的。如果不判null直接使用${}打印,会报模板错误,效果如下:

2.1.6 global 全局代码声明

语法如下:

<#global name=value>或<#global name1=value1 name2=value2 ... nameN=valueN>或<#global name>
  capture this</#global>

global使用和assign用法类似,只不过global声明是全局的,所有的命名空间都是可见的。

2.1.7 if elseif else 条件判断

语法如下:

<#if condition>
  ...<#elseif condition2>
  ...<#elseif condition3>
  ...
...<#else>
  ...</#if>

示例如下:

<#assign x=1 ><#if x==1>
    x is 1<#elseif x==2>
    x is 2<#else>
    x is not 1</#if>

2.1.8 import 引入模板

语法: <#import path as hash>

示例如下

footer.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body>this is footer.ftl<#assign copy="来自 王磊的博客"></body></html>

index.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body><#import "footer.ftl" as footer>${footer.copy}</body></html>

最终输出内容:

来自 王磊的博客

2.1.9 include 嵌入模板

语法: <#include path>

示例如下

footer.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body>this is footer.ftl<#assign copy="来自 王磊的博客"></body></html>

index.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body><#include "footer.ftl"></body></html>

最终内容如下:

this is footer.ftl

2.1.10 list, else, items, sep, break 循环

2.1.10.1 正常循环

输出1-3的数字,如果等于2跳出循环,代码如下:

<#list 1..3 as n>
    ${n}    <#if n==2>
        <#break>
    </#if></#list>

注意:“1..3”等于[1,2,3]。

结果: 1 2

2.1.10.2 使用items输出

示例如下:

<#list 1..3><ul><#items as n>
    <li>${n}</li></#items></ul></#list>
2.1.10.3 sep 使用

跳过最后一项

<#list 1..3 as n>
    ${n}    <#sep>,</#sep></#list>

最终结果:1 , 2 , 3

2.1.10.4 数组最后一项

代码如下:

<#list 1..3 as n>
    ${n}    <#if !n_has_next>
    最后一项    </#if></#list>

使用“变量_has_next”判断是否还有下一个选项,来找到最后一项,最终的结果:1 2 3 最后一项

2.1.11 macro 宏

宏:是一个变量名的代码片段,例如:

<#macro sayhi name>
    Hello, ${name}</#macro><@sayhi "Adam" />

相当于声明了一个名称为“sayhi”有一个参数“name”的宏,使用自定义标签“@”调用宏。

输出的结果: Hello, Adam

2.1.12 switch, case, defalut, break 多条件判断

示例代码如下:

<#assign animal="dog" ><#switch animal>
    <#case "pig">
        This is pig        <#break>
    <#case "dog">
        This is dog        <#break>
    <#default>
            This is Aaimal</#switch>

2.1.13 扩展知识

指令自动忽略空格特性

FreeMarker会忽略FTL标签中的空白标记,所以可以直接写:

<#list ["老王","老李","老张"]
    as
            p>    ${p}
</#list>

即使是这个格式也是没有任何问题的,FreeMarker会正常解析。

2.2 表达式

2.2.1 字符串拼接

字符拼接代码:

<#assign name="ABCDEFG">${"Hello, ${name}"}

结果:Hello, ABCDEFG

2.2.2 算术运算

2.2.2.1 算术符

算术符有五种:

  • +

  • -

  • *

  • /

  • % 求余(求模)

示例代码:

${100 - 10 * 20}

输出:

-100
2.2.2.2 数值转换
${1.999?int}

输出:

1

注意:数值转换不会进行四舍五入,会舍弃小数点之后的。

2.2.3 内建函数(重点)

内建函数:相当于我们Java类里面的内置方法,非常常用,常用的内建函数有:时间内建函数、字符内建函数、数字内建函数等。

2.2.3.1 单个问号和两个问号的使用和区别

单问号:在FreeMarker中用单个问号,来调用内建函数,比如: ${"admin"?length} 查看字符串“admin”的字符长度,其中length就是字符串的内建函数。

双引号:表示用于判断值是否为null,比如:

<#if admin??>
    Admin is not null</#if>
2.2.3.2 字符串内建函数
2.2.3.2.1 是否包含判断

使用contains判断,代码示例:

<#if "admin"?contains("min")>
   min<#else >not min</#if>

输出:

min
2.2.3.2.2 大小写转换

示例代码:

<#assign name="Adam">${name?uncap_first} 
${name?upper_case}
${name?cap_first}
${name?lower_case}

输出:

adam ADAM Adam adam

更多的字符串内建函数:https://freemarker.apache.org/docs/ref_builtins_string.html

2.2.3.3 数字内建函数

示例代码:

${1.23569?string.percent}
${1.23569?string["0.##"]}
${1.23569?string["0.###"]}

输出:

124% 1.24 1.236

注意:

  • 使用string.percent计算百分比,会自动四舍五入。

  • 使用“?string["0.##"]”可以自定义取小数点后几位,会自动四舍五入。

2.2.3.4 时间内建函数
2.2.3.4.1 时间戳转换为任何时间格式

代码:

<#assign timestamp=1534414202000>${timestamp?number_to_datetime?string["yyyy/MM/dd HH:mm"]}

输出:

2018/08/16 18:10
2.2.3.4.2 时间格式化

示例代码:

<#assign nowTime = .now>${nowTime} <br />${nowTime?string["yyyy/MM/dd HH:mm"]} <br />

输出:

2018-8-16 18:33:50 2018/08/16 18:33

更多内建方法:https://freemarker.apache.org/docs/ref_builtins.html

三、Spring Boot 集成

3.1 集成环境

  • Spring Boot 2.0.4

  • FreeMaker 2.3.28

  • JDK 8

  • Windows 10

  • IDEA 2018.2.1

3.2 集成步骤

3.2.1 pom.xml 添加FreeMaker依赖

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

3.2.2 application.properties 配置模板

主要配置,如下:

## Freemarker 配置spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.cache=falsespring.freemarker.charset=UTF-8spring.freemarker.check-template-location=truespring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=falsespring.freemarker.expose-session-attributes=falsespring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
配置项 类型 默认值 建议值 说明
spring.freemarker.template-loader-path String classpath:/templates/ 默认 模版存放路径
spring.freemarker.cache bool true 默认 是否开启缓存,生成环境建议开启
spring.freemarker.charset String - UTF-8 编码
spring.freemarker.content-type String text/html text/html content-type类型
spring.freemarker.suffix String .ftl .ftl 模板后缀
spring.freemarker.expose-request-attributes bool false false 设定所有request的属性在merge到模板的时候,是否要都添加到model中
spring.freemarker.expose-session-attributes bool false false 设定所有HttpSession的属性在merge到模板的时候,是否要都添加到model中.
spring.freemarker.request-context-attribute String - request RequestContext属性的名称

更多配置:

# FREEMARKER (FreeMarkerProperties)
spring.freemarker.allow-request-override=false # Whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.allow-session-override=false # Whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.cache=false # Whether to enable template caching.
spring.freemarker.charset=UTF-8 # Template encoding.
spring.freemarker.check-template-location=true # Whether to check that the templates location exists.
spring.freemarker.content-type=text/html # Content-Type value.
spring.freemarker.enabled=true # Whether to enable MVC view resolution for this technology.
spring.freemarker.expose-request-attributes=false # Whether all request attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-session-attributes=false # Whether all HttpSession attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-spring-macro-helpers=true # Whether to expose a RequestContext for use by Spring's macro library, under the name "springMacroRequestContext".
spring.freemarker.prefer-file-system-access=true # Whether to prefer file system access for template loading. File system access enables hot detection of template changes.
spring.freemarker.prefix= # Prefix that gets prepended to view names when building a URL.
spring.freemarker.request-context-attribute= # Name of the RequestContext attribute for all views.
spring.freemarker.settings.*= # Well-known FreeMarker keys which are passed to FreeMarker's Configuration.
spring.freemarker.suffix=.ftl # Suffix that gets appended to view names when building a URL.
spring.freemarker.template-loader-path=classpath:/templates/ # Comma-separated list of template paths.
spring.freemarker.view-names= # White list of view names that can be resolved.

3.2.3 编写HTML代码

<html><head>
    <title>王磊的博客</title></head><body><div>
    Hello,${name}</div></body></html>

3.2.4 编写Java代码

新建index.java文件,Application.java(入口文件)代码不便,index.java代码如下:

import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controller@RequestMapping("/")public class Index {    @RequestMapping("/")    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView("/index");
        modelAndView.addObject("name", "老王");        return modelAndView;
    }
}

关键代码解读:

  1. @Controller注解:标识自己为控制器,只需要配置@RequestMapping之后,就可以把用户URL映射到控制器;

  2. 使用ModelAndView对象,指定视图名&添加视图对象。

3.2.5 运行

执行上面4个步骤之后,就可以运行这个Java项目了,如果是IDEA使用默认快捷键“Shift + F10”启动调试,在页面访问:http://localhost:8080/ 就可看到如下效果:

四、参考资料

FreeMarker官方文档:https://freemarker.apache.org/

FreeMarker翻译的中文网站:http://freemarker.foofun.cn/toc.html

原文出处:https://www.cnblogs.com/vipstone/p/9559052.html

作者:慕斯王
链接:http://www.imooc.com/article/72698
来源:慕课网

介绍

FreeMarker是一款免费的Java模板引擎,是一种基于模板和数据生成文本(HMLT、电子邮件、配置文件、源代码等)的工具,它不是面向最终用户的,而是一款程序员使用的组件。

FreeMarker最初设计是用来在MVC模式的Web开发中生成HTML页面的,所以没有绑定Servlet或任意Web相关的东西上,所以它可以运行在非Web应用环境中。

发展史

FreeMarker第一版在1999年未就发布了,2002年初使用JavaCC(Java Compiler Compiler是一个用Java开发的语法分析生成器)重写了FreeMarker的核心代码,2015年FreeMarker代码迁移到了Apache下。

GitHub地址:https://github.com/apache/freemarker

工作原理

FreeMarker模板存储在服务器上,当有用户访问的时候,FreeMarker会查询出相应的数据,替换模板中的标签,生成最终的HTML返回给用户,如下图:

二、FreeMarker基础使用

基础使用分为3部分,这3部分组成了FreeMarker:

  • 指令

  • 表达式

指令是FreeMarker用来识别转换的特殊标签,表达式是标签里具体的语法实现,其他部分是一些不好分类的模板。

2.1 指令

使用FTL(freemarker template language)标签来调用指令。

指令速览:

  • assign

  • attempt, recover

  • compress

  • escape, noescape

  • flush

  • ftl

  • function, return

  • global

  • if, else, elseif

  • import

  • include

  • list, else, items, sep, break

  • local

  • macro, nested, return

  • noparse

  • nt

  • setting

  • stop

  • switch, case, default, break

  • t, lt, rt

  • visit, recurse, fallback

  • 用户自定义标签

下来我们分别来看每个指令对应具体使用。

2.1.1 assign 代码声明

assign 分为变量和代码片段声明两种。

2.1.1.1 变量声明

可以是单变量声明,或多变量声明,下面是多变量声明的示例:

<#assign name="adam" age=18 "sex"="man">${name} - ${age} - ${"sex"}

单个变量的话,只写一个就可以了。

2.1.1.2 代码片段声明
<#assign code>
    <#list ["java","golang"] as c>
        ${c}    </#list></#assign>${code}

其中 ${code} 是用来执行方法的,如果不调用话,代码片段不会执行。

2.1.2 attempt, recover 异常指令

attempt(尝试), recover(恢复)指令类似于程序的try catch,示例如下:

<#attempt>
   i am ${name}   <#recover>
   error name</#attempt>

如果有变量“name”就会正常显示,显示“i am xxx”,如果没有变量就会显示“error name”。

2.1.3 compress 压缩代码移除空白行

<#compress>
  1 2  3   4    5     
  test only   I said, test only</#compress>1 2  3   4    5 test only I said, test only

效果如下:

对空白不敏感的格式,移除空白行还是挺有用的功能。

2.1.4 escape, noescape 转义,不转义

2.1.4.1 escape使用
<#escape x as x?html>
    ${firstName}
    ${lastName}</#escape>

上面的代码,类似于:

${firstName?html}
${lastName?html}

Java代码:

@RequestMapping("/")public ModelAndView index() {
  ModelAndView modelAndView = new ModelAndView("/index");
  modelAndView.addObject("firstName", "<span style='color:red'>firstName</span>");
  modelAndView.addObject("lastName", "lastName");  return modelAndView;
}

最终的效果是:

2.1.4.2 “?html”语法解析

单问号后面跟的是操作函数,类似于Java中的方法名,html属于内建函数的一个,表示字符串会按照HTML标记输出,字符替换规则如下:

  • < 替换为 &lt;

  • > 替换为 &gt;

  • & 替换为 &amp;

  • " 替换为 &quot;

2.1.4.3 noescape使用

HTML代码:

<#escape x as x?html>
    <#noescape>
        ${firstName}    </#noescape>
    ${lastName}</#escape>

Java代码:

@RequestMapping("/")public ModelAndView index() {
  ModelAndView modelAndView = new ModelAndView("/index");
  modelAndView.addObject("firstName", "<span style='color:red'>firstName</span>");
  modelAndView.addObject("lastName", "lastName");  return modelAndView;
}

最终效果:

2.1.5 function, return 方法声明

代码格式:

<#function name param1 param2 ... paramN>
  ...
  <#return returnValue>
  ...
</#function>
  • name 为方法名称

  • param1, param2,paramN 方法传递过来的参数,可以有无限个参数,或者没有任何参数

  • return 方法返回的值,可以出现在function的任何位置和出现任意次数

示例代码如下:

<#function sum x y z>
    <#return x+y+z></#function>${sum(5,5,5)}

注意:function如果没有return是没有意义的,相当于返回null,而function之中信息是不会打印到页面的,示例如下:

<#function wantToPrint>
    这里的信息是显示不了的</#function><#if wantToPrint()??>
    Message:${wantToPrint()}</#if>

“??”用于判断值是否是null,如果为null是不执行的。如果不判null直接使用${}打印,会报模板错误,效果如下:

2.1.6 global 全局代码声明

语法如下:

<#global name=value>或<#global name1=value1 name2=value2 ... nameN=valueN>或<#global name>
  capture this</#global>

global使用和assign用法类似,只不过global声明是全局的,所有的命名空间都是可见的。

2.1.7 if elseif else 条件判断

语法如下:

<#if condition>
  ...<#elseif condition2>
  ...<#elseif condition3>
  ...
...<#else>
  ...</#if>

示例如下:

<#assign x=1 ><#if x==1>
    x is 1<#elseif x==2>
    x is 2<#else>
    x is not 1</#if>

2.1.8 import 引入模板

语法: <#import path as hash>

示例如下

footer.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body>this is footer.ftl<#assign copy="来自 王磊的博客"></body></html>

index.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body><#import "footer.ftl" as footer>${footer.copy}</body></html>

最终输出内容:

来自 王磊的博客

2.1.9 include 嵌入模板

语法: <#include path>

示例如下

footer.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body>this is footer.ftl<#assign copy="来自 王磊的博客"></body></html>

index.ftl 代码如下:

<html><head>
    <title>王磊的博客</title></head><body><#include "footer.ftl"></body></html>

最终内容如下:

this is footer.ftl

2.1.10 list, else, items, sep, break 循环

2.1.10.1 正常循环

输出1-3的数字,如果等于2跳出循环,代码如下:

<#list 1..3 as n>
    ${n}    <#if n==2>
        <#break>
    </#if></#list>

注意:“1..3”等于[1,2,3]。

结果: 1 2

2.1.10.2 使用items输出

示例如下:

<#list 1..3><ul><#items as n>
    <li>${n}</li></#items></ul></#list>
2.1.10.3 sep 使用

跳过最后一项

<#list 1..3 as n>
    ${n}    <#sep>,</#sep></#list>

最终结果:1 , 2 , 3

2.1.10.4 数组最后一项

代码如下:

<#list 1..3 as n>
    ${n}    <#if !n_has_next>
    最后一项    </#if></#list>

使用“变量_has_next”判断是否还有下一个选项,来找到最后一项,最终的结果:1 2 3 最后一项

2.1.11 macro 宏

宏:是一个变量名的代码片段,例如:

<#macro sayhi name>
    Hello, ${name}</#macro><@sayhi "Adam" />

相当于声明了一个名称为“sayhi”有一个参数“name”的宏,使用自定义标签“@”调用宏。

输出的结果: Hello, Adam

2.1.12 switch, case, defalut, break 多条件判断

示例代码如下:

<#assign animal="dog" ><#switch animal>
    <#case "pig">
        This is pig        <#break>
    <#case "dog">
        This is dog        <#break>
    <#default>
            This is Aaimal</#switch>

2.1.13 扩展知识

指令自动忽略空格特性

FreeMarker会忽略FTL标签中的空白标记,所以可以直接写:

<#list ["老王","老李","老张"]
    as
            p>    ${p}
</#list>

即使是这个格式也是没有任何问题的,FreeMarker会正常解析。

2.2 表达式

2.2.1 字符串拼接

字符拼接代码:

<#assign name="ABCDEFG">${"Hello, ${name}"}

结果:Hello, ABCDEFG

2.2.2 算术运算

2.2.2.1 算术符

算术符有五种:

  • +

  • -

  • *

  • /

  • % 求余(求模)

示例代码:

${100 - 10 * 20}

输出:

-100
2.2.2.2 数值转换
${1.999?int}

输出:

1

注意:数值转换不会进行四舍五入,会舍弃小数点之后的。

2.2.3 内建函数(重点)

内建函数:相当于我们Java类里面的内置方法,非常常用,常用的内建函数有:时间内建函数、字符内建函数、数字内建函数等。

2.2.3.1 单个问号和两个问号的使用和区别

单问号:在FreeMarker中用单个问号,来调用内建函数,比如: ${"admin"?length} 查看字符串“admin”的字符长度,其中length就是字符串的内建函数。

双引号:表示用于判断值是否为null,比如:

<#if admin??>
    Admin is not null</#if>
2.2.3.2 字符串内建函数
2.2.3.2.1 是否包含判断

使用contains判断,代码示例:

<#if "admin"?contains("min")>
   min<#else >not min</#if>

输出:

min
2.2.3.2.2 大小写转换

示例代码:

<#assign name="Adam">${name?uncap_first} 
${name?upper_case}
${name?cap_first}
${name?lower_case}

输出:

adam ADAM Adam adam

更多的字符串内建函数:https://freemarker.apache.org/docs/ref_builtins_string.html

2.2.3.3 数字内建函数

示例代码:

${1.23569?string.percent}
${1.23569?string["0.##"]}
${1.23569?string["0.###"]}

输出:

124% 1.24 1.236

注意:

  • 使用string.percent计算百分比,会自动四舍五入。

  • 使用“?string["0.##"]”可以自定义取小数点后几位,会自动四舍五入。

2.2.3.4 时间内建函数
2.2.3.4.1 时间戳转换为任何时间格式

代码:

<#assign timestamp=1534414202000>${timestamp?number_to_datetime?string["yyyy/MM/dd HH:mm"]}

输出:

2018/08/16 18:10
2.2.3.4.2 时间格式化

示例代码:

<#assign nowTime = .now>${nowTime} <br />${nowTime?string["yyyy/MM/dd HH:mm"]} <br />

输出:

2018-8-16 18:33:50 2018/08/16 18:33

更多内建方法:https://freemarker.apache.org/docs/ref_builtins.html

三、Spring Boot 集成

3.1 集成环境

  • Spring Boot 2.0.4

  • FreeMaker 2.3.28

  • JDK 8

  • Windows 10

  • IDEA 2018.2.1

3.2 集成步骤

3.2.1 pom.xml 添加FreeMaker依赖

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

3.2.2 application.properties 配置模板

主要配置,如下:

## Freemarker 配置spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.cache=falsespring.freemarker.charset=UTF-8spring.freemarker.check-template-location=truespring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=falsespring.freemarker.expose-session-attributes=falsespring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
配置项 类型 默认值 建议值 说明
spring.freemarker.template-loader-path String classpath:/templates/ 默认 模版存放路径
spring.freemarker.cache bool true 默认 是否开启缓存,生成环境建议开启
spring.freemarker.charset String - UTF-8 编码
spring.freemarker.content-type String text/html text/html content-type类型
spring.freemarker.suffix String .ftl .ftl 模板后缀
spring.freemarker.expose-request-attributes bool false false 设定所有request的属性在merge到模板的时候,是否要都添加到model中
spring.freemarker.expose-session-attributes bool false false 设定所有HttpSession的属性在merge到模板的时候,是否要都添加到model中.
spring.freemarker.request-context-attribute String - request RequestContext属性的名称

更多配置:

# FREEMARKER (FreeMarkerProperties)
spring.freemarker.allow-request-override=false # Whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.allow-session-override=false # Whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.cache=false # Whether to enable template caching.
spring.freemarker.charset=UTF-8 # Template encoding.
spring.freemarker.check-template-location=true # Whether to check that the templates location exists.
spring.freemarker.content-type=text/html # Content-Type value.
spring.freemarker.enabled=true # Whether to enable MVC view resolution for this technology.
spring.freemarker.expose-request-attributes=false # Whether all request attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-session-attributes=false # Whether all HttpSession attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-spring-macro-helpers=true # Whether to expose a RequestContext for use by Spring's macro library, under the name "springMacroRequestContext".
spring.freemarker.prefer-file-system-access=true # Whether to prefer file system access for template loading. File system access enables hot detection of template changes.
spring.freemarker.prefix= # Prefix that gets prepended to view names when building a URL.
spring.freemarker.request-context-attribute= # Name of the RequestContext attribute for all views.
spring.freemarker.settings.*= # Well-known FreeMarker keys which are passed to FreeMarker's Configuration.
spring.freemarker.suffix=.ftl # Suffix that gets appended to view names when building a URL.
spring.freemarker.template-loader-path=classpath:/templates/ # Comma-separated list of template paths.
spring.freemarker.view-names= # White list of view names that can be resolved.

3.2.3 编写HTML代码

<html><head>
    <title>王磊的博客</title></head><body><div>
    Hello,${name}</div></body></html>

3.2.4 编写Java代码

新建index.java文件,Application.java(入口文件)代码不便,index.java代码如下:

import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controller@RequestMapping("/")public class Index {    @RequestMapping("/")    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView("/index");
        modelAndView.addObject("name", "老王");        return modelAndView;
    }
}

关键代码解读:

  1. @Controller注解:标识自己为控制器,只需要配置@RequestMapping之后,就可以把用户URL映射到控制器;

  2. 使用ModelAndView对象,指定视图名&添加视图对象。

3.2.5 运行

执行上面4个步骤之后,就可以运行这个Java项目了,如果是IDEA使用默认快捷键“Shift + F10”启动调试,在页面访问:http://localhost:8080/ 就可看到如下效果:

四、参考资料

FreeMarker官方文档:https://freemarker.apache.org/

FreeMarker翻译的中文网站:http://freemarker.foofun.cn/toc.html

原文出处:https://www.cnblogs.com/vipstone/p/9559052.html

作者:慕斯王
链接:http://www.imooc.com/article/72698
来源:慕课网

FreeMaker入门介绍的更多相关文章

  1. C# BackgroundWorker组件学习入门介绍

    C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...

  2. 初识Hadoop入门介绍

    初识hadoop入门介绍 Hadoop一直是我想学习的技术,正巧最近项目组要做电子商城,我就开始研究Hadoop,虽然最后鉴定Hadoop不适用我们的项目,但是我会继续研究下去,技多不压身. < ...

  3. [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上)

    最近在使用Python爬取网页内容时,总是遇到JS临时加载.动态获取网页信息的困难.例如爬取CSDN下载资源评论.搜狐图片中的“原图”等,此时尝试学习Phantomjs和CasperJS来解决这个问题 ...

  4. [Python爬虫] scrapy爬虫系列 <一>.安装及入门介绍

    前面介绍了很多Selenium基于自动测试的Python爬虫程序,主要利用它的xpath语句,通过分析网页DOM树结构进行爬取内容,同时可以结合Phantomjs模拟浏览器进行鼠标或键盘操作.但是,更 ...

  5. JavaScript入门介绍(二)

    JavaScript入门介绍 [函数] 函数function 是Javascript的基础模块单元,用于代码的复用.信息影藏和组合调用. function a(){} 函数对象Function Lit ...

  6. JavaScript入门介绍(一)

    JavaScript入门介绍 [经常使用的调试工具][w3school.com.cn在线编辑] [Chrome浏览器 开发调试工具]按F121.代码后台输出调试:console.log("t ...

  7. .NET 4 并行(多核)编程系列之一入门介绍

    .NET 4 并行(多核)编程系列之一入门介绍 本系列文章将会对.NET 4中的并行编程技术(也称之为多核编程技术)以及应用作全面的介绍. 本篇文章的议题如下:  1. 并行编程和多线程编程的区别.  ...

  8. .NET读写Excel工具Spire.Xls使用(1)入门介绍

    原文:[原创].NET读写Excel工具Spire.Xls使用(1)入门介绍 在.NET平台,操作Excel文件是一个非常常用的需求,目前比较常规的方法有以下几种: 1.Office Com组件的方式 ...

  9. Linux入门介绍

    Linux入门介绍 一.Linux 初步介绍 Linux的优点 免费的,开源的 支持多线程,多用户 安全性好 对内存和文件管理优越 系统稳定 消耗资源少 Linux的缺点 操作相对困难 一些专业软件以 ...

随机推荐

  1. vue知识总结

    vue: 渐进式JavaScript 框架 Vue项目构建 npm install -g vue vue init webpack-simple my-project cd my-project np ...

  2. vue命令行错误处理

    全局安装vue/cli时:npm install -g @vue/cli (1)Error: EACCES: permission denied, access '/usr/local/lib/nod ...

  3. Raize 重新编译

    最近项目用到了Raize5的日历控件, 需要在中文版本与英文版本中切换显示, 这个需要修改 RzPopups.pas, 修改了需要重新编译. 费老大劲了.   首选修改 RzBorder.pas, 不 ...

  4. 《Whitelabel Error Page 404》 对于Springboot初学者可能出现问题的原因

    whitelabel error page异常一定是有原因的,比如,访问路径不对,解析不对,注解忘记引入等.对于初学者,一定要注意一点,程序只加载Application.java所在包及其子包下的内容 ...

  5. poi 设置单元格公式

    Cell cell= rowF2.createCell(18);cell.setCellFormula("=Q20*R20");

  6. 读取控制器PHP代码文件,并分析数据存到数据库,再重新读出生成PHP文件

    <?php namespace app\publicSport\controller\verify; /**  * 引入基类  */ use app\publicSport\controller ...

  7. 获取某个元素第一次出现在数组(json数组)的索引

    function firstIndex(arr, text) { // 若元素不存在在数组中返回-1 let firstVal = -1; for (let i = 0; i < arr.len ...

  8. Vue 组件&组件之间的通信 父子组件的通信

    在Vue的组件内也可以定义组件,这种关系成为父子组件的关系: 如果在一个Vue实例中定义了component-a,然后在component-a中定义了component-b,那他们的关系就是: Vue ...

  9. Ubuntu查看crontab运行日志

    Ubuntu服务器/var/log下没有cron日志,这里记录一下如何ubuntu server如何查看crontab日志 crontab记录日志修改rsyslogsudo vim /etc/rsys ...

  10. 自制操作系统Antz(7)——实现内核 (上)

    Antz系统更新地址: https://www.cnblogs.com/LexMoon/category/1262287.html Linux内核源码分析地址:https://www.cnblogs. ...