FreeMarker详细介绍
1. 什么是网页静态化技术
随着用户访问量以及数据量的增大,网页静态化技术方案如今越来越流行。什么是网页静态化技术呢?简单来说就是将网页以纯静态方式的形式进行展现。
网页静态化技术与缓存技术的比较:
共同点:都可以减小数据库的访问压力。
区别:
-
缓存技术适用于小规模的数据。以及一些经常变动的数据。
-
网页静态化技术适用于大规模但是变化不太频繁的数据。
网页静态化技术的应用场景:
- 新闻门户网站的文章类型频道一般都用到了网页静态化技术。点击新闻直接会跳到静态化的页面。
- 电商网站的商品详情页也十分常用,在存储商品的时候会生成静态化页面,点击商品详情,会直接跳到生成的商品详情的静态化页面。
- 网页静态化技术可以结合Nginx这种高性能web服务器来提高并发访问量。
2. FreeMarker概述
FreeMarker
是一款用Java
语言编写的模板引擎,用它可以通过模板和要改变的数据来生成输出文本(例如HTML
网页,配置文件,源代码等),作为用来实现网页静态化技术的一种手段。FreeMarker
的使用率大大超过其他一些技术。对于系统中频繁使用数据库进行查询但是内容更新很小的应用,都可以用FreeMarker
将网页静态化,这样就避免了大量的数据库访问请求,从而提高网站的性能。
3. FreeMarker入门案例
步骤一:创建Maven项目
参考链接:Tomcat + Maven创建Web项目 + 在IDEA中使用Tomcat
步骤二:导入Freemarker的maven坐标
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
步骤三:创建模板文件
模板文件中有四种元素:
- 文本,直接输出的部分
- 注释,即<#–…–>格式不会输出
- 插值(
Interpolation
):即${…}部分,将使用数据模型中的部分替代输出 FTL
指令:FreeMarker
指令,和HTML
标记类似,名字前加#
予以区分,不会输出
Freemarker
的模板文件后缀可以任意,一般建议为ftl
。
在D盘创建名称为test.ftl
的模板文件,内容如下:
步骤四:生成文件
-
创建一个
Configuration
对象,直接new
一个对象。构造方法的参数就是freemarker
的版本号。 -
设置模板文件所在的路径。
-
设置模板文件使用的字符集。一般就是
utf-8
。 -
加载一个模板,创建一个模板对象。
-
创建一个模板使用的数据集,可以是
pojo
也可以是map
。一般是Map
。 -
创建一个
Writer
对象,一般创建FileWriter
对象,指定生成的文件名。 -
调用模板对象的
process
方法输出文件。 -
关闭流。
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
// 1. 创建配置类
Configuration configuration = new Configuration(Configuration.getVersion());
// 2. 设置模板所在的目录
configuration.setDirectoryForTemplateLoading(new File("E:\\"));
// 3. 设置字符集
configuration.setDefaultEncoding("utf-8");
// 4. 加载模板
Template template = configuration.getTemplate("test.ftl");
// 5. 创建模型数据
Map map = new HashMap();
map.put("name", "lsm");
map.put("message", "FreeMarker入门");
// 6. 创建Writer对象
Writer writer = new FileWriter(new File("e:\\test.html"));
// 7. 输出
template.process(map, writer);
// 8. 关闭writer对象
writer.close();
}
}
运行程序后会在E
盘下面生成test.html
网页,如下进行信息查看。
4. FreeMarker常见指令
4.1 assign指令
assign指令用于在页面上定义一个变量
定义简单类型
<#assign linkman="周先生">
联系人:${linkman}
定义对象类型
<#assign info={"mobile":"13812345678",'address':'北京市昌平区'} >
电话:${info.mobile} 地址:${info.address}
4.2 include指令
include
指令用于模板文件的嵌套
创建模板文件head.ftl
<h1>lsmUJN</h1>
修改入门案例中的test.ftl
,在test.ftl
模板文件中使用include
指令引入上面的模板文件
<#include "head.ftl"/>
4.3 if指令
if
指令用于判断
在模板文件中使用if
指令进行判断
<#if success=true>
你已通过实名认证
<#else>
你未通过实名认证
</#if>
在Java
代码中为success
变量赋值
map.put("success", true);
4.4 list指定
list
指令用于遍历
在模板文件中使用list
指令进行遍历
<#list goodsList as goods>
商品名称: ${goods.name} 价格:${goods.price}<br>
</#list>
在Java
代码中为goodsList
赋值
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);
5. Freemarker在项目中的应用
在跟着做黑马的传智健康项目的时候在移动端需要用到FreeMarker
技术,需要把生成移动端套餐列表静态页面和套餐详情静态页面,这样就不用重复的访问数据库,造成数据访问的压力。
套餐列表页面模板文件:mobile_setmeal.ftl
套餐详情页面模板文件:mobile_setmeal_detail.ftl
对Spring
配置文件进行相关配置:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!--指定模板文件所在目录-->
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<!--指定字符集-->
<property name="defaultEncoding" value="UTF-8" />
</bean>
<context:property-placeholder location="classpath:freemarker.properties"/>
生成静态页面:这里是在新增套餐的时候才生成静态界面,感觉这里在编辑套餐和删除套餐的时候都需要生成静态页面,对于编辑套餐可以和新增套餐一样,生成静态页面,但对于删除套餐操作暂时还没解决。
@Service(interfaceClass = SetMealService.class)
@Transactional
public class SetMealServiceImpl implements SetMealService {
@Autowired
private JedisPool jedisPool;
@Autowired
private SetMealDao setMealDao;
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Value("${out_put_path}")
private String outPutPath; // 从属性文件中读取要生成的html对应的目录
// 新增套餐
public void add(SetMeal setMeal, Integer[] checkGroupIds) {
setMealDao.add(setMeal);
this.setSetMealAndCheckGroup(setMeal.getId(), checkGroupIds);
jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES, setMeal.getImg());
// 新增套餐后需要重新生成静态页面
generateMobileStaticHtml();
}
// 生成静态页面
private void generateMobileStaticHtml() {
List<SetMeal> setMealList = setMealDao.selectAll();
// 生成套餐列表静态页面
generateMobileSetMealListHtml(setMealList);
// 生成套餐详情静态页面
generateMobileSetMealDetailHtml(setMealList);
}
// 生成套餐列表静态页面
private void generateMobileSetMealListHtml(List<SetMeal> setMealList) {
Map map = new HashMap();
map.put("setmealList", setMealList);
generateHtml("mobile_setmeal.ftl", "m_setmeal.html", map);
}
// 生成套餐详情静态页面
private void generateMobileSetMealDetailHtml(List<SetMeal> setMealList) {
for(SetMeal setMeal : setMealList){
Map map = new HashMap();
map.put("setmeal", setMealDao.findById(setMeal.getId()));
generateHtml("mobile_setmeal_detail.ftl", "setmeal_detail_" + setMeal.getId() + ".html", map);
}
}
/**
* 生成html文件
* @param templateName:ftl模版文件名
* @param htmlName:生成的html文件名称
* @param map: 数据
*/
public void generateHtml(String templateName, String htmlName, Map map){
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Writer out = null;
try {
// 加载模板
Template template = configuration.getTemplate(templateName);
out = new FileWriter(new File(outPutPath + "/" + htmlName));
template.process(map, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
再次对移动端进行访问的时候,就不会访问数据库了,减轻了数据库访问压力,直接访问对应的静态界面。
参考链接:https://blog.csdn.net/weixin_44454512/article/details/109877418