**网页静态化解决方案_Freemarker*

版权声明:文章为作者自己原创文章,转载请注明出处。 https://blog.csdn.net/qq_37128049/article/details/84950572

课程目标

1. 掌握Freemarker常用的指令与内建函数
2. 完成商品详细页的数据显示
3. 完成商品详细页的动态效果
4. 完成商品详细页读取SKU信息的业务逻辑
5. 完成商品审核调用功能

前述

1. 使用范围:
	* 网页静态化解决方案在实际开发中运用比较多,比如新闻网站,门户网站中的新闻频道或者是文章类的频道;

2. 原理:
	* 把数据库中的文件事先提取出来,通过文件io的写入,在服务器上生成这样一个文件,用户在访问的时候直接访问这个静态网页;用户访问的时候直接访问网页,而不用访问数据库了;
	* 什么是Freemarker?
		- Freemarker是一个用于java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTPP。它不仅仅用用表现层的实现技术,而且还可以用于生成XML,JSP或Java等。

3. 优点:
	1. 适用性广:   
		* 不单单是新闻栏目等,电商网站的商品详细页也有大量的信息,同样可以用网页静态化来解决;
	2. 减轻数据库压力:
		* 用户直接访问文件而不用访问数据库;
	3. 利于SEO: 
		* 容易提高排名
	4. 适合大规模且变化不频繁:
		* 缓存只能小规模的数据,网页静态化能存储大规模的数据
	5. 纯静态化可用Niginx:'
		* Nginx可以承载5万并发,而tomcat只有几百;所以tomcat高并发还得需要集群;


4. 创建模板文件
	* 四元素:
		1. 文本, 直接输出的部分
		2. 注释, 即<#-- ... --> 格式不会输出
		3. 插值(interpolation):即${...} 部分,将使用数据模型中的部分替代输出
		4. FTL指令:FreeMarker指令,和HTML标记类似,名字前加# 予以区分,不会输出;

FTL指令:

1. assign指令:		-->达到在创建模板页面中的map集合put值的效果,指令是在模板中;

	1. 定义简单类型:
		<#assign linkman="周先生">
		联系人:${linkman}
	2. 定义对象类型:
		<#assign info={"mobile":"13301231231",'address':'北京市昌平区王府街'}>
		电话:${info.mobile}			地址:${info.address}

2. include指令:    包含其他的模板,用于模板文件的嵌套,可以复用;比如常见的头部尾部是复用的;
	1. 创建模板文件:head.ftl:
		<h1>黑马信息网</h1>
	2. 在模板文件中使用include指令引入模板
		<#include "head.ftl">

3. if指令:
	1. 在模板文件body中:	
			<#-- if 指令-->
			<#if success=true>
			您已通过实名认证
			<#else>
			您未通过审核
			</#if>
	2. 在demo运行程序中:
			 map.put("success",false);

	3. 分析: 
		* 先给出条件,条件可以为if,else两种也可以只if,然后再demo程序中必须给success一个布尔值,否则程序运行报错;
		* 模板中的等号可以使用"=" 也可以使用"=="进行判断,意义一样;


4.list指令
		
	1. 作用:可以将list中的值进行遍历输出
	2. 实现步骤:
		1. demo运行程序:
					  //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);

		2. 模板表	
				<#list goodsList as goods>
		   		 ${goods_index+1} 商品名称:${goods.name}商品价格:${goods.price}<br/>
				</#list>
		3. 分析:
			1.  通过先给值,然后里面进行遍历输出;
			2.  ${goods_index} 可以打印出索引号;如果需要顺序排列+1即可;

内建函数:

5.1. 获取集合大小:

	1. 格式:变量+?+函数名称
	2. 代码演示:
		1. 显示集合记录:
			<#-- 内建函数-->
			一共${goodsList?size} 条记录

5.2. 转换JSON字符串为对象:
	1. 代码
		<#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
		<#assign data=text?eval />
		开户行:${data.bank} 账号:${data.account}	
	2. ?eval进行转换,如果是数组也可以进行转换;

    5.3. 日期格式化:
    
    	1. 代码中对变量赋值:
    		map.put("today", new Date());
    	2.在模板文件中加入
    		当前日期:${today?date} <br>
    		当前时间:${today?time} <br>
    		当前日期+时间:${today?datetime} <br>
    		日期格式化: ${today?string("yyyy 年 MM 月 dd 日 hh:mm:ss")}
    
    5.4. 数字转换为字符串
    
    	1. 代码中对变量赋值:
    		map.put("point", 102920122);
    	2. 修改模板:
    		累计积分:${point}
    	3. 我们会发现数字会以每三位一个分隔符显示,有些时候我们不需要这个分隔符,就需要将数字转为字符串,使用内建函数c:
    		累计积分:${point?c}
    
    
    
    5.5. 空值运算符		" ?? "
    	1. 现象:如果你在模板中使用了变量但是在代码中没有对变量赋值,那么运行生成时会抛出异常。但是有些时候,有的变量确实是 null,怎么解决这个问题呢?
    	2. 判断某变量是否存在:	" ?? "
    		1. 解析:用法为:variable??,如果该变量存在,返回 true,否则返回 false
    		2. 示例:
    			<#if aaa??>
    			aaa 变量存在
    			<#else>
    			aaa 变量不存在
    			</#if>
    
    5.6. 缺失变量默认值:	" ! "
    	1. 现象:我们除了可以判断是否为空值,额也可以使用!对null值做转换处理
    	2. 在模板加入:
    		${aaa!'bbb没有被赋值'}
    	3. 分析: 这个比上面的?判断更为简单,不需要if语句,这里!后的'' 也可以使用"";

运算符

1. 算数运算符:
	FreeMarker 表达式中完全支持算术运算,FreeMarker 支持的算术运算符包括:+, - , * , / , %
2. 逻辑运算符:
	逻辑运算符有如下几个: <#if aaa=true && bbb=false> </#if>
	逻辑与:&&
	逻辑或:||
	逻辑非:!
	逻辑运算符只能作用于布尔值,否则将产生错误
3. 比较运算符:
	表达式中支持的比较运算符有如下几个:
	1 =或者==:判断两个值是否相等.
	2 !=:判断两个值是否不等.
	3 >或者 gt:判断左边值是否大于右边值 <#if (aaa=>1) >
	4 >=或者 gte:判断左边值是否大于等于右边值
	5 <或者 lt:判断左边值是否小于右边值
	6 <=或者 lte:判断左边值是否小于等于右边值A=1;A!=”1” 字符串不能使用大于 大于等于 小于 小于等于

	1. 举例:
		<#--3. 运算符举例-->
		<#if (100>10)>
		100肯定比10大啊
		</#if>      <br/>
	2. 分析:
		* if里面的判断语句必须用括号引起来,如果不引起来的话大于小于使用gt,或者gte
		* 因为如果不引起来,使用">"号作为大于,容易与前面的<if 标签进行融合,程序运行错误;

Demo小程序 – 前面代码完整版总结:

1. pom.xml:
		<?xml version="1.0" encoding="UTF-8"?>
		<project xmlns="http://maven.apache.org/POM/4.0.0"
	         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	    <modelVersion>4.0.0</modelVersion>
	    <groupId>cn.itcast.demo</groupId>
	    <artifactId>freemarkerDemo</artifactId>
	    <version>1.0-SNAPSHOT</version>
	    <dependencies>
	        <dependency>
	            <groupId>org.freemarker</groupId>
	            <artifactId>freemarker</artifactId>
	            <version>2.3.22</version>
	        </dependency>
	    </dependencies>
		</project>  

2. src/main/java/cn/itcast/demo/Test.java:
			package cn.itcast.demo;
			import freemarker.template.Configuration;
			import freemarker.template.Template;
			import freemarker.template.TemplateException;
			import java.io.File;
			import java.io.FileWriter;
			import java.io.IOException;
			import java.io.Writer;
			import java.util.*;
			public class Test {
		   	 public static void main(String[] args) throws IOException, TemplateException {
		        //创建一个配置对象,获取该对象的版本
		        Configuration configuration=new Configuration(Configuration.getVersion());
		        //获取模板所在目录
		        configuration.setDirectoryForTemplateLoading(new File("D:\\freemarkerDemo\\src\\main\\resources"));
		        //设置编码集
		        configuration.setDefaultEncoding("utf-8");
		        //获取模板对象
		        Template template=configuration.getTemplate("test.ftl");
		        //给值
		        Map map=new HashMap();
		        map.put("name","张三丰");
		        map.put("message","欢迎来到神奇的Freemarker世界!");
		        //if指令默认给值
		        map.put("success",false);
		
		        //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);
		
		        //给日期格式化赋值
		        map.put("today",new Date());
		        //数字转为字符串给值
		        map.put("point",135465);
		
		
		
		        //输出对象
		        Writer out=new FileWriter("D:\\freemarkerDemo\\src\\main\\java\\cn\\itcast\\demo\\test.html");
		        //输出
		        template.process(map,out);
		        //关闭
		        out.close();
		    }
		}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
3. src/main/java/cn/itcast/demo/test.html:
	* 这个是输出的文件,运行后即可得到此文件,内容略;


4. src/main/resources/head.ftl:
	<h1>黑马信息网</h1>

5. src/main/resources/test.ftl:
				<html>
			<head>
			    <title>demo</title>
			    <meta charset="utf-8">
			
			</head>
			<#-- freemarker注释:我是一个注释,不会输出-->
			<!-- html注释 我会输出-->
			<body>
			<#--FTL指令-->
			<#--FTL指令 1. include指令-->
			<#include "head.ftl">
			
			<#-- 插值 -->
			${name},你好。${message}<br/>
			
			<#--FTL指令2.  assign指令-->
			<#assign linkman="周先生">
			${linkman}  <br/>
			
			<#--FTL指令 3. if 指令-->
			<#if success=true>
			您已通过实名认证
			<#else>
			您未通过审核
			</#if><br/>
			
			<#--FTL指令 4.  list指令 -->
			-----商品列表--------<br/>
			<#list goodsList as goods>
			    ${goods_index+1} 商品名称:${goods.name}商品价格:${goods.price}<br/>
			</#list>
			
			<#-- 内建函数-->
			
			<#--内建函数 1.获取集合长度 -->
			一共${goodsList?size} 条记录         <br/>
			
			<#--内建函数 2.将JSON字符串转换为对象-->
			<#assign text="{'bank':'招商银行','account':'546135615464'}">
			<#assign data=text?eval>
			开户行:${data.bank}  卡号:${data.account}         <br/>
			
			
			<#--内建函数 3.日期格式化-->
			当前日期:${today?date}   <br/>
			当前时间:${today?time}  <br/>
			当前日期+时间: ${today?datetime}      <br/>
			自定义日期:${today?string("yyyy年MM月dd日 HH:mm:ss")}       <br/>
			
			<#--内建函数 4. 数字转为字符串-->
			<#--显示普通数字-->
			累计积分:${point}    <br/>
			<#--显示字符串数字-->
			累计积分:${point?c}
			
			
			<#--运算符-->
			<#--1.空值运算符-->
			<#if aaa??>
			aaa存在: ${aaa}
			<#else >
			aaa不存在
			</#if>
			
			<#-- 2. 缺少变量默认值: !-->
			${bbb!"bbb不存在"}     <br/>
			
			<#--3. 运算符举例-->
			<#if (100>10)>
			100肯定比10大啊
			</#if>      <br/>
			
			</body>
			</html>                                                               

实战总结:

1. 工作中使用网页静态化解决方案:
	1. 环境搭建:
		1. 导入依赖:pom.xml:
			<dependency>
	            <groupId>org.freemarker</groupId>
	            <artifactId>freemarker</artifactId>
	            <version>2.3.23</version>
	        </dependency>
	    2. 	引入spring提供的支持:resources/spring/applicationContext-service.xml:	
		     <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
			   <property name="templateLoaderPage" value="/WEB-INF/ftl/"/>
			   <property name="defaultEncoding" value="UTF-8"/>
		   </bean>   
		3. 最好还应该路径动态化,不要写死:       resources/properties/page.properties:			[程序不一定在windows系统中运行,Linux等没有D盘C盘,所以应该将地址提取出来]
			pagedir=d:\\Item\\

	2. 实战要点:
		* 在调用数据库中的数据的时候,首先创建一个interface,再创建一个impl实现类实现它的获取方法;
		* 在获取方法中 代码示例:
							@Service
				public class ItemPageServiceImpl implements ItemPageService {
				    //注入配置对象
				    @Autowired
				    private FreeMarkerConfigurer freeMarkerConfigurer;
				
				    //注入虚拟路径
				    @Value("${pageidr}")
				    private String pagedir;
				
				    //注入商品数据访问层
				    @Autowired
				    private TbGoodsMapper goodsMapper;
				
				    //注入商品详细页访问层
				    @Autowired
				    private TbGoodsDescMapper goodsDescMapper;
				
				    @Override
				    public boolean genItemHtml(Long goodsId) {
				        //获得配置对象
				        Configuration configuration=freeMarkerConfigurer.getConfiguration();
				        try {
				            //获得模板
				            Template template=configuration.getTemplate("item.ftl");
				            //设置字符集
				            configuration.setDefaultEncoding("UTF-8");
				            //设置数据模型
				            Map dataModel=new HashMap<>();
				            //注入主表数据
				            TbGoods goods=goodsMapper.selectByPrimaryKey(goodsId);
				            dataModel.put("goods",goods);
				            //注入商品扩展表数据
				            TbGoodsDesc goodsDesc=goodsDescMapper.selectByPrimaryKey(goodsId);
				            dataModel.put("goodsDesc",goodsDesc);
				            //设置生成目录
				            Writer out=new FileWriter(pagedir+goodsId+".html");
				            //输出
				            template.process(dataModel,out);    //输出
				            out.close();
				            return true;
				        } catch (Exception e) {
				            e.printStackTrace();
				            return false;
				
				        }
				    }
				}
	 
		* 我们创建模板的时候,应该将页面的头部和底部给提取出来,创建一个新的ftl文件,然后使用<#include>标签进行调用; 
		* 在展示数据的时候,需要从数据库中拿数据,但是数据库中的数据是JSON格式的,我们需要使用?eval 进行数据转换,转换成对象即可调用了;
		* 在展示大量数据需要用到遍历集合的时候,可以使用 <#list> 方法进行遍历使用 ${..} 方法展示数据,使用<#if 变量??> 判断是否为空或 变量!'' 进行判断;
		* 转换为对象后的数据调用的名称需要注意,因为是键值对,所以调用的时候需要参照数据库中的key值和value值,否则无法调用;
		* 如果数据库中存入的数据不是键值对的JSON格式,则可以直接进行遍历输出;
		* 查询面包屑分类列表的时候,可以先查询出该商品的id值,然后查出三级分类的各名称,然后再在页面中${...} 显示即可;
		* 如果是选中的东西如何显示? 可以先在controller.js中创建一个方法,接收前端页面来的key值和value值;
		* 在工作中比如商品详情页面的生成,可以放在商品审核的时候完成,当商品审核通过点击事件启动的时候,就生成静态页面;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

猜你喜欢

转载自blog.csdn.net/qq_37128049/article/details/84950572
今日推荐