Freemarker
一、简介
电商项目中,由于商品详情页面访问量较大,为了节省网络资源,提高用户体验度,一般我们使用Freemarker技术将商品详情页静态化。
Freemarker不支持java脚本代码,而是使用EL表达式来展示数据。Freemarker的设计初衷就是:模板+数据模型=输出,模板只负责在页面中展示,不涉及任何逻辑代码,而所有的逻辑代码都是有数据模型来处理。我们在每一次点击上架就会生成一次新的静态页面来替换原来的静态页面。
二、基本语法
@RequestMapping("/toDemo01")
public ModelAndView toDemo01(){
// 去到demo01.ftl文件
ModelAndView modelAndView = new ModelAndView("demo01");
// 1.传递普通属性值去ftl文件界面
modelAndView.addObject("id",10010);
modelAndView.addObject("name","无人机");
modelAndView.addObject("price",999.99D);
modelAndView.addObject("createDate",new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
modelAndView.addObject("hireDate",new Date());
// 2.list集合的传值
List<Object> list = new ArrayList<>();
list.add("123");
list.add(123.33D);
list.add(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
list.add(456);
modelAndView.addObject("list",list);
// 3.对象属性的传值
WebProductImgEntity webProductImgEntity = new WebProductImgEntity();
webProductImgEntity.setId(10086L);
webProductImgEntity.setImgurl("http://pvmv81qrv.bkt.clouddn.com//zijin/8a32b1ae576c4c87b04319f9af212bc0.jpeg");
webProductImgEntity.setProductid(10010L);
modelAndView.addObject("model",webProductImgEntity);
// 4.map集合的传值
Map<String,Object> map = new HashMap<>();
map.put("id",110);
map.put("discount",0.98D);
map.put("birthday",new Date());
map.put("username","zhiheng");
modelAndView.addObject("map",map);
return modelAndView;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo01.ftl</title>
</head>
<body>
<div style="margin-left: 200px">
<p>
<h3>1.普通属性的传值</h3>
<h4>id:${id}</h4>
<h4>name:${name}</h4>
<h4>price:${price}</h4>
<h4>price2:${price?string("0.0")}</h4>
<h4>createDate:${createDate}</h4>
<h4>hireDate:${hireDate?string("yyyy-MM-dd HH:mm:ss")}</h4>
</p>
<hr>
<p>
<h3>2.list集合的传值</h3>
<#list list as i>
<h4>${i_index}--------${i}</h4>
</#list>
</p>
<hr>
<p>
<h3>3.对象的传值</h3>
<h4>id:${model.id}</h4>
<h4>imgurl:${model.imgurl}</h4>
<h4>productid:${model.productid}</h4>
</p>
<hr>
<p>
<h3>4.Map集合的传值</h3>
<h4>id:${map.id}</h4>
<h4>discount:${map.discount}</h4>
<h4>birthday:${map.birthday?string("yyyy/MM/dd HH:mm:ss")}</h4>
<h4>username:${map.username}</h4>
</p>
</div>
</body>
</html>
三、使用步骤:
<!--引入freemaker-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
package com.java.web.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileWriter;
import java.util.Map;
/**
* @author Liushun
* @date Created in 2019/8/03 11:54
* @description freemarker生成html文件的工具类
*/
public class FreemarkerUtil {
public static String makeHtml(Long id, Map<String,Object> dataMap, Configuration configuration){
// 1.获得生成文件的文件路径
String filepath = "D:\\JAVA_Project\\zhiheng\\freemarker\\products\\"+id + ".html";
// 2.通过文件路径新建一个空的文件
File file = new File(filepath);
try {
// 3.获得目标文件的输出流对象
FileWriter fw = new FileWriter(file);
// 4.读取freemarker html页面的生成模板
Template template = configuration.getTemplate("Product.ftl");
// 5.完成html页面的复制生成(dataMap为生成时的动态数据,fw为目标文件的输出流)
template.process(dataMap,fw);
// 6.关流
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
return filepath;
}
}
@EnableScheduling // 开启任务调度
@Service
@Transactional
public class WebProductDetailServiceImpl extends BaseServiceImpl<WebProductDetailEntity> implements WebProductDetailService {
@Autowired
private Configuration configuration;
// 每个3分钟更新商品详情页面
@Scheduled(cron = "0 0/3 * * * ?") // 间隔3分钟执行
@Override
public void makeProductHtml() throws Exception {
// 查询数据库得到商品详情信息
List<WebProductDetailEntity> webProductDetailEntities = baseMapper.queryAll();
for (int i = 0; i < webProductDetailEntities.size(); i++){
// 得到商品详情对象
WebProductDetailEntity webProductDetailEntity = webProductDetailEntities.get(i);
// 新建数据集合
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("title",webProductDetailEntity.getTitle());
// 新建商品详情图片的查询条件
WebProductImgEntity webProductImgParams = new WebProductImgEntity();
// 将商品id设置为查询条件:查询出某一个商品的详情图片数据
webProductImgParams.setProductid(webProductDetailEntity.getId());
// 根据商品详情id查询商品的详情图片数据
List<WebProductImgEntity> webProductImgEntities = webProductImgMapper.queryManyByPramas(webProductImgParams);
// 新建一个商品图片路径的集合
List<String> imgUrlList = new ArrayList<>();
// 通过循环将商品的图片设置进去
for (int j = 0; j< webProductImgEntities.size(); j++){
imgUrlList.add(webProductImgEntities.get(j).getImgurl());
}
dataMap.put("imgUrlList",imgUrlList);
dataMap.put("subTitle",webProductDetailEntity.getSubtitle());
dataMap.put("price",webProductDetailEntity.getPrice());
dataMap.put("type",webProductDetailEntity.getType());
dataMap.put("color",webProductDetailEntity.getColor());
FreemarkerUtil.makeHtml(webProductDetailEntity.getId(),dataMap,configuration);
}
System.out.println("此方法在" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()) + "被执行了");
}
}
备注:因篇幅问题,有部分没有展示出来,有不懂得可以私聊我,互相交流。