同福

Java的模板引擎FreeMarker的使用技巧【20210417】

介绍

介绍

开发一个网站需要考虑几个问题,首先就是编程语言,其次就是开发框架,最后还需要考虑模板引擎。编程语言这里我们自然是Java语言了;开发框架就是编写网站后端功能模块的基础框架,这里福哥选择的是TFSpring框架;最后的模板引擎,就是在制作用户界面所使用的处理模块,也就是MVC架构里面说的视图,这里福哥就要引出今天的主角FreeMarker了。

FreeMarker是非常有名的基于Java语言的模板引擎,它支持非常丰富的语法,它有非常好的开发团队,所以福哥才会在TFSpring框架里面将FreeMarker作为模板引擎来使用。

安装

依赖

这是freemarker的依赖,写到pom.xml里面就可以了。

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>

自动配置

默认情况下springboot会自动配置freemarker,为了演示方便我们先把它关闭了。

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, FreeMarkerAutoConfiguration.class})
@SpringBootApplication
public class TfspringApplication {

示例

下面是一个标准的freemarker的示例。

首先通过Configuration对象的setDirectoryForTemplateLoading方法指定模板根目录。

然后通过Configuration对象的getTemplate方法创建模板对象。

最后通过Template对象的process方法整合模板内容并写入输出对象。

Java

Configuration configuration = new Configuration(Configuration.getVersion());
Template template;
Map data = new LinkedHashMap();
StringWriter stringWriter = new StringWriter();

configuration.setDirectoryForTemplateLoading(new File(System.getProperty("user.dir") + "/src/main/resources/template"));
template = configuration.getTemplate("test.ftl");
template.process(data, stringWriter);

return stringWriter.toString();

模板

模板文件是test.ftl,这里福哥只写了一句话。

福哥,你好!

效果

home/topic/2021/0418/10/2ced37ccba04418702dd5bdf6d184459.jpg

使用

福哥写了一个示例,演示如何将后端程序的变量指定给前端模板来使用的。

实体User

这是实体User的定义。

@Data
public class User {
    Integer id;
    String name;
    String link;
}

Java

下面演示如何向前端模板指定变量。

configuration.setDirectoryForTemplateLoading(new File(System.getProperty("user.dir") + "/src/main/resources/template"));
template = configuration.getTemplate("test.ftl");

data.put("int", 10);
data.put("double", 1.2);
data.put("string", "福哥");
data.put("html", "<h3>福哥</h3>");
User user = new User();
user.setId(35);
user.setName("鬼谷子叔叔");
user.setLink("https://tongfu.net/home/35.html");
data.put("entity", user);

template.process(data, stringWriter);

模板

下面是前端模板代码的示例。

<table border="1">
    <tr>
        <td>整型</td><td>${int}</td>
    </tr>
    <tr>
        <td>双精</td><td>${double}</td>
    </tr>
    <tr>
        <td>字符串</td><td>${string}</td>
    </tr>
    <tr>
        <td>HTML</td><td>${html}</td>
    </tr>
    <tr>
        <td>实体</td><td>
            <a href="${entity.link}">(${entity.id})${entity.name}</a>
        </td>
    </tr>
</table>

效果

执行程序可以看到如下的页面效果。

home/topic/2021/0418/10/31d2783976aeeeeee5073205b4940172.jpg

语法

变量

  • 模板变量使用${...}表示,“...”就是Map对象的键名。

  • 模板变量如果是一个结构可以通过${xxx.yyy}调用结构属性,“xxx”是结构对应的Map对象的键名,“yyy”是结构的属性名称。

实体User

@Data
public class User {
    Integer id;
    String name;
    String link;
}

Java

data.put("name", "同福");
User user = new User();
user.setId(35);
user.setName("鬼谷子叔叔");
user.setLink("https://tongfu.net/home/35.html");
data.put("entity", user);

前端模板

<table border="1">
    <tr>
        <td>普通变量</td><td>${name}</td>
    </tr>
    <tr>
        <td>结构变量</td><td>
            <a href="${entity.link}">(${entity.id})${entity.name}</a>
        </td>
    </tr>
</table>

效果

home/topic/2021/0418/11/d806d86c1f11705e080c8121bb5a21a5.jpg

遍历循环

  • 对集合变量进行遍历,就可以拿到集合的一个一个的元素。

  • 对Map变量进行遍历,就可以拿到Map的键名和键。

Java

Map user = new LinkedHashMap();
user.put("id", 35);
user.put("name", "鬼谷子叔叔");
user.put("link", "https://tongfu.net/home/35.html");
data.put("user", user);

模板

<table border="1">
    <tr>
        <td>索引</td><td>Key</td><td>Item</td>
    </tr>
    <#list user ? keys as key>
    <tr>
        <td>${key_index}</td><td>${key}</td><td>${user[key]}</td>
    </tr>
    </#list>
</table>

效果

home/topic/2021/0418/11/c574f84225bcd9bc17a7f04aef95d2c9.jpg

按次循环

  • 按次循环需要知道起始数值和结束数值,对应数组循环的话需要考虑结束值是数组长度减一。

Java

String[] languages = new String[]{
    "PHP",
    "Python",
    "Java",
    "JavaScript",
    "C/C++",
    "Asp.net"
};
data.put("lang", languages);

模板

<table border="1">
    <tr>
        <td>索引</td><td>语言</td>
    </tr>
    <#list 0..5 as i>
    <tr>
        <td>${i}</td><td>${lang[i]}</td>
    </tr>
    </#list>
</table>

效果

home/topic/2021/0418/11/2a89da837c3c0414ff02da2d173c162a.jpg

嵌套循环

  • 嵌套遍历循环需要注意子级名称的类型不要弄错了,后端Java要和前端模板严格对应。

Java

List<Map<String, Object>> map = new LinkedList<>();
Map<String, Object> item;
item = new HashMap<>();
item.put("hot", 100);
item.put("lang", "PHP");
map.add(item);
item = new HashMap<>();
item.put("hot", 200);
item.put("lang", "Python");
map.add(item);
item = new HashMap<>();
item.put("hot", 300);
item.put("lang", "Java");
map.add(item);
item = new HashMap<>();
item.put("hot", 60);
item.put("lang", "JavaScript");
map.add(item);
item = new HashMap<>();
item.put("hot", 30);
item.put("lang", "C/C++");
map.add(item);
item = new HashMap<>();
item.put("hot", 80);
item.put("lang", "Asp.net");
map.add(item);
data.put("lang", map);

模板

<table border="1">
    <tr>
        <td>热度</td><td>语言</td>
    </tr>
    <#list lang as langItem>
    <tr>
        <#list langItem ? keys as key>
        <td>${langItem[key]}</td>
        </#list>
    </tr>
    </#list>
</table>

效果

home/topic/2021/0418/13/09bf7b5614f151f2402adba557d39aaa.jpg

判断语句

  • 判断语句同样使用“&&”和“||”表示“与”和“或”关系,使用“==”和“!=”表示相等和不相等。

  • 判断语句“else if”需要连着写成“elseif”这样,否则会报错。

比较运算符

  • ==:表示两边相等

  • !=:表示两边不相等

  • gt:表示左边大于右边

  • gte:表示左边大于等于右边

  • lt:表示左边小于右边

  • lte:表示左边小于等于右边

Java

List<Map<String, Object>> map = new LinkedList<>();
Map<String, Object> item;
item = new HashMap<>();
item.put("hot", 100);
item.put("lang", "PHP");
map.add(item);
item = new HashMap<>();
item.put("hot", 200);
item.put("lang", "Python");
map.add(item);
item = new HashMap<>();
item.put("hot", 300);
item.put("lang", "Java");
map.add(item);
item = new HashMap<>();
item.put("hot", 60);
item.put("lang", "JavaScript");
map.add(item);
item = new HashMap<>();
item.put("hot", 30);
item.put("lang", "C/C++");
map.add(item);
item = new HashMap<>();
item.put("hot", 80);
item.put("lang", "Asp.net");
map.add(item);
data.put("lang", map);

模板

<table border="1">
    <tr>
        <td>热度</td><td>语言</td>
    </tr>
    <#list lang as langItem>
    <tr>
        <td>
            <#if langItem.hot gte 200>
            <span style="color: red;">${langItem.hot}</span>
            <#elseif langItem.hot gte 100>
            <span style="color: blue;">${langItem.hot}</span>
            <#else>
            <span>${langItem.hot}</span>
            </#if>
        </td>
        <td>
            ${langItem.lang}
        </td>
    </tr>
    </#list>
</table>

效果

home/topic/2021/0418/14/896375c5d24ccca14a64fc1898af2af3.jpg

总结

好了,今天福哥给童鞋们讲解了Java的模板引擎FreeMarker的使用技巧,相信大家今后无论是使用TFSpring框架开发项目,还是在自己的项目里面使用FreeMarker模板引擎,都可以制作出非常漂亮的用户界面了。