1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用Freemarker来页面静态化 与Spring整合使用

使用Freemarker来页面静态化 与Spring整合使用

时间:2019-07-10 05:09:01

相关推荐

使用Freemarker来页面静态化 与Spring整合使用

页面静态化介绍

页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为

通过静态化技术生成的静态网页,这样用户在访问网页时,服务器直接给用户响应静态html页面,没有

了动态查询数据库的过程。

那么这些静态HTML页面还需要我们自己去编写吗?其实并不需要,我们可以通过专门的页面静态化技

术帮我们生成所需的静态HTML页面,例如:Freemarker、thymeleaf等。

FreeMarker

freemarker中文官方文档

什么是FreeMarker?

实际上用程序语言编写的程序就是模板。 FTL (代表FreeMarker模板语言)。 这是为编写模板设计的非常简单的编程语言。

模板(FTL编程)是由如下部分混合而成的:

文本:文本会照着原样来输出。

插值:这部分的输出会被计算的值来替换。插值由 ${ and } 所分隔(或者 #{ and },这种风格已经不建议再使用了;点击查看更多)。

FTL 标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。

注释:注释和HTML的注释也很相似,但它们是由 <#-- 和 -->来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。

我们来看一个具体的模板。其中的内容已经用颜色来标记了: 文本, 插值, FTL 标签, 注释。为了看到可见的 换行符, 这里使用了

请注意非常重要的一点: 插值 仅仅可以在 文本 中使用。 (也可以是字符串表达式;请参考 后续内容)

FTL 标签 不可以在其他 FTL 标签 和 插值中使用。比如, 这样做是 错误 的: <#if <#include ‘foo’>=‘bar’>…</#if>

Freemarker的指令(在下面的案列中解释)

简单使用Freemarker来生成静态化页面

搭建maven工程

pom.xml

需要引入freemarker的依耐

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>FreemarkerDemo</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency></dependencies></project>

创建模板文件

模板文件中有四种元素:

1、文本,直接输出的部分 2、注释,即<#–…-->格式不会输出 3、插值(Interpolation):即${…}部分,

将使用数据模型中的部分替代输出 4、FTL指令:FreeMarker指令,和HTML标记类似,名字前加#予以

区分,不会输出

Freemarker的模板文件后缀可以任意,一般建议为ftl。

test.ftl

<html><head><meta charset="utf-8"><title>Freemarker入门</title></head><body><#--我只是一个注释,我不会有任何输出 -->${name}你好,${message}<hr><#--assign指令用于在页面上定义一个变量 --><#--(1)定义简单类型assign指令用于在页面上定义一个变量 定义变量方便测试生产的模板内容--><#assign linkman="付先生">联系人:${linkman}<#--(2)定义对象类型--><#assign info={"mobile":"13812345678",'address':'重庆'} >电话:${info.mobile} 地址:${info.address}<hr><#--include指令用于模板文件的嵌套 引入模板文件 模板文件的目录会在java代码中指定configuration.setDirectoryForTemplateLoading(new File(文件路径)); --><#include "head.ftl"/><hr><#--if指令用于判断--><#--(1)在模板文件中使用if指令进行判断 (2)在java代码中为success变量赋值--><#if success=true>你已通过实名认证<#else>你未通过实名认证</#if><hr><#--list指令用于遍历 (1)在模板文件中使用list指令进行遍历 (2)在java代码中为goodsList赋值--><#list goodsList as goods>商品名称: ${goods.name} 价格:${goods.price}<br></#list></body></html>

head.ftl

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>头部</title></head><body><h1>---------------头部信息---------------</h1></body></html>

生成静态文件的java代码

使用步骤:

第一步:创建一个 Configuration 对象,直接 new 一个对象。构造方法的参数就是 freemarker的版本

号。

第二步:设置模板文件所在的路径。

第三步:设置模板文件使用的字符集。一般就是 utf-8。

第四步:加载一个模板,创建一个模板对象。

第五步:创建一个模板使用的数据集,可以是 pojo 也可以是 map。一般是 Map。

第六步:创建一个 Writer 对象,一般创建 FileWriter 对象,指定生成的文件名。

第七步:调用模板对象的 process 方法输出文件。

第八步:关闭流。

package com.fs.testfreemarker;import freemarker.template.Configuration;import freemarker.template.Template;import java.io.*;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class TestFreemarker {public static void main(String[] args) throws Exception {//1.创建配置类Configuration configuration = new Configuration(Configuration.getVersion());//2.设置模板所在的目录configuration.setDirectoryForTemplateLoading(new File("E:\\IdeaProjects\\Demo01\\test\\FreemarkerDemo\\src\\main\\resources\\template"));//3.设置字符集configuration.setDefaultEncoding("utf-8");//4.加载模板// Template template = configuration.getTemplate("test.ftl");Template template = configuration.getTemplate("test.ftl","utf-8");//5.创建数据模型,我们模板中有 ${name}你好,${message} 所以我们通过map来设置数据Map map = new HashMap();map.put("name", "小付");map.put("message", "欢迎使用freemarker!");//为if指令赋值map.put("success", true);//为list指令赋值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);//6.创建Writer对象FileOutputStream file= new FileOutputStream("E:\\IdeaProjects\\Demo01\\test\\FreemarkerDemo\\src\\main\\resources\\out\\testFreemarker.html");//utf-8字符集输出OutputStreamWriter out = new OutputStreamWriter(file, "utf-8");//7.输出template.process(map, out);//8.关闭Writer对象out.close();}}

运行后生成的html静态页面testFreemarker.html

<html><head><meta charset="utf-8"><title>Freemarker入门</title></head><body>小付你好,欢迎使用freemarker!<hr>联系人:付先生电话:13812345678 地址:重庆<hr><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>头部</title></head><body><h1>---------------头部信息---------------</h1></body></html><hr>你已通过实名认证<hr>商品名称: 苹果 价格:5.8<br>商品名称: 香蕉 价格:2.5<br>商品名称: 橘子 价格:3.2<br></body></html>

浏览器打开

freemarker与Spring整合

applicationContext.xml

在application.xml中使用Bean标签将org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer交给spring的IOC管理

就可以使用FreeMarkerConfigurer得到Configuration 进行静态页面生成

//注入freemarker@Autowiredprivate FreeMarkerConfigurer freeMarkerConfigurer;//通过FreeMarkerConfigurer获得freemarker的配置类Configuration configuration = freeMarkerConfigurer.getConfiguration();

<!-- 配置freemarker--><bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"><!-- 指定模板文件的位子--><property name="templateLoaderPath" value="/WEB-INF/ftl"/><!-- 指定字符集--><property name="defaultEncoding" value="UTF-8"/></bean><!-- 引入动态生成的静态页面地址,在java中使用@Value注入--><context:property-placeholder location="classpath:freemarker.properties"/>

freemarker.properties

# freemarker动态生成的静态页面输出的地址,实际生产部署是生产在tomcat的中,outPut.Path=E:/IdeaProjects/projectOne/fs-health-parent/health_mobile/src/main/webapp/pages

java(下面的代码为伪代码.理解思想)

public class Test {//注入freemarker@Autowiredprivate FreeMarkerConfigurer freeMarkerConfigurer;//从properties文件中注入freemarker生成的静态页面地址@Value("${outPut.Path}")private String outPutPath;/*由于我们现在health_mobile用户微信使用的页面的数据是异步请求获得的,用户每次使用套餐预约的时候,setmeal.html,setmeal_detail.html中的套餐数据,检查组,检查项,都是每次查询数据库得到的,这样加载页面十分缓慢,效率太低,用户体验度极差等解决上述方法,我们使用页面静态化技术,让我们用户每次访问的页面数据事写死的,静态的,每次用户访问,直接传递页面到用户端解析,不在请求数据库查询,这个静态化页面中的数据如何填充?我们查询的数据只要不进行修改,页面数据是不会变的,所以,我们后台只要添加了套餐信息,或者修改了套餐信息就使用freemarker,先创建一个模板页面,页面中的数据使用 assign指令 include指令 if指令 list指令等指令(查看WEB-INF中的文件)填充原来数据应该显示的位子,然后我们使用java代码动态的去指令的位子替换数据,然后生成一个静态页面,这样,用户访问的时候加载静态页面就不每次访问去数据库查询数据,大大提高了效率*///每当用户点击添加套餐的时候,执行生成静态页面方法generateMobileStaticHtml();/*** 生成移动静态Html* 下面的代码是伪代码,dao代表调用dao查询的数据*/public void generateMobileStaticHtml(){//准备模板文件所需要的数据,先查询出所有的套餐信息,调用自己的查询所有方法List<Setmeal> setMealList = dao.findAll();//生成套餐列表静态页面mobile_setmeal.ftl,数据查询出来赋值给这个模板将这个模板变成静态页面HashMap<String, Object> objectHashMap = new HashMap<>();//将查询出的值放在map中objectHashMap.put("setmealList",setMealList);//调用生成静态页面,生成套餐列表静态页面generateHtml("mobile_setmeal.ftl","m_setmeal.html",objectHashMap);//生成套餐详情静态页面mobile_setmeal_detail.ftl数据查询出来赋值给这个模板,变成静态页面//由于点击套餐详情页面是多个的,查询出的每个详情页面就生成一个动态页面,页面的名字由套餐的id结尾//先遍历集合,得到每个套餐的id,在查询出每个套餐信息的详细数据,然后使用模板生成静态页面for (Setmeal setmeal : setMealList) {//每次遍历就封装一个mapHashMap<String, Object> stringObjectHashMap = new HashMap<>();//封装查询套餐信息的详细信息,封装到map中,让freemarker来解析出静态页面stringObjectHashMap.put("setmeal",this.findSetMealDetails(setmeal.getId()));//然后调用方法生成静态页面.名字结尾拼接上idthis.generateHtml("mobile_setmeal_detail.ftl","setmeal_detail_"+setmeal.getId()+".html",stringObjectHashMap);}}/*** 用于生成静态页面Dao指定的目录* @param templateName 传递的模板名称* @param htmlName 生成的模板名称* @param objectHashMap 查询出的值,赋值给模板的指令符*/public void generateHtml(String templateName, String htmlName, Map<String, Object> objectHashMap){//通过FreeMarkerConfigurer获得freemarker的配置类Configuration configuration = freeMarkerConfigurer.getConfiguration();//由于我们spring配置文件中添加freeMarkerConfigurer这个bean的时候指定了模板文件的地址,所以我们这里只需要传递模板文件的名就可以Writer out = null;try {//给定模板文件,得到模板对象Template template = configuration.getTemplate(templateName);//指定模板对象生成的文件地址(在properties文件中指定了的)以及文件名称File file = new File(outPutPath + "\\" + htmlName);//创建字符缓冲流out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));//给模板文件写入数据,并传入一个字符输出流,template.process(objectHashMap,out);} catch (Exception e) {e.printStackTrace();}finally {//判断字符缓存流是否为nullif (out != null){try {//不为null.说明有数据,那就刷新流,写到磁盘中out.flush();} catch (IOException e) {e.printStackTrace();}}}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。