一
1.通过模板+数据–》生成静态化页面
2.缺点:数据不实时
3.适用于于数据长时间不更新的情况
二、在项目中搭建freemarker
freemarker.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--配置freemarker的实现类 -->
<bean id="staticPageService" class="cn.zhou.core.service.staticpage.StaticPageServiceImpl">
<!-- set注入 -->
<property name="freeMarkerConfigurer">
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!--配置模板加载路径 -->
<property name="templateLoaderPath" value="/WEB-INF/ftl/"></property>
<!--配置读取模板的语言格式 -->
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
</property>
</bean>
</beans>
jar包
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
</dependency>
适用于单独某个网页的静态化 这里对productDetail.html做静态化
调用:生产静态化界面了,下次访问设置不去controller层,直接跳转静态化页面
/**
*
* 生成静态页面
*
* @author Administrator
*
*/
// 实现接口ServletContextAware,是为了获取servletContext,进而获取项目路径
public class StaticPageServiceImpl implements StaticPageService, ServletContextAware {
// @Autowired
// private Configuration conf;//注入配置对象
private Configuration conf;
// 不用注解注入,set注入
// private FreeMarkerConfigurer freeMarkerConfigurer;//注入配置对象
// freeMarkerConfig 注解得到,得到后通过getConfiguration(),将值注入conf,所以conf也不要注解
public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
this.conf = freeMarkerConfigurer.getConfiguration();
}
// 静态方法,rootMap填充数据
public void productIndex(Map<String, Object> rootMap,Integer id) {
// conf.setDirectoryForTemplateLoading(new File(""));//设置模板加载路径,已经在freemark.xml中配置
// 获取模板
// 输出流 从内存写到磁盘中UTF-8格式
Writer out = null;
String path = getPath("/html/product/"+id+".html");
File file=new File(path);
// /html/product/这个文件不存在
if(!file.getParentFile().exists()){
//创建/html/product/文件夹,mkdirs多级创建
file.getParentFile().mkdirs();
}
try {
// 从从磁盘读到内存中UTF-8格式,已经在freemark.xml中配置
//模板:productDetail.html 实际是/WEB-INF/ftl/productDetail.html
Template template = conf.getTemplate("productDetail.html");
out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
//填充数据
template.process(rootMap, out);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 获取名称对应的路径
public String getPath(String name) {
return servletContext.getRealPath(name);
}
private ServletContext servletContext;
public void setServletContext(ServletContext servletContext) {
// set注入
this.servletContext = servletContext;
}
}
静态化页面在项目中的生成,这里以商品上架的时候,同时生产静态化页面
//商品上架
@RequestMapping(value="/product/isShow.do")
public String isShow(Integer[] ids,Integer pageNo,String name,Integer brandId,Integer isShow,ModelMap modelMap){
//Integer[] ids 为商品id数组
Product product=new Product();
//设置上架
product.setIsShow(1);
if(ids!=null && ids.length>0){
for (Integer id : ids) {
product.setId(id);
productService.updateProductByKey(product);
//freemarker静态化
Map<String, Object> rootMap=new HashMap<String, Object>();
// sku集合
List<Sku> skuList = skuService.getStock(id);
rootMap.put("skuList", skuList);
// 商品集合
product = productService.getProductByKey(id);
rootMap.put("product", product);
// 颜色集合
List<Color> colors = new ArrayList<Color>();
//去重复
for (Sku sku : skuList) {
//判断集合中是否已经有此颜色对象了
if (!colors.contains(sku.getColor())) {
colors.add(sku.getColor());
}
}
rootMap.put("colors", colors);
//生成静态化页面
staticPageService.productIndex(rootMap, id);
}
}
页面模板
<script type="text/javascript">
//刷新页面第一个a标签触发click事件
$(function(){
$("#colors a:first").trigger("click");
//商品购买+-
//商品+,jquery点击触发事件
$("#add").click(function(){
//获取件数
var num=$("#num").val();
num++;
if(num>buyLimit){
alert("此商品只能买"+buyLimit+"件");
return;
}
//赋值
$("#num").val(num);
});
//商品-,jquery点击触发事件
$("#sub").click(function(){
//获取件数
var num=$("#num").val();
num--;
if(num==0){
return;
}
//赋值
$("#num").val(num);
});
})
//全局变量
var colorId;//颜色Id
var skuId;//skuId
var buyLimit;//限购
//点击选择颜色id为颜色的ID
function colorToRed(target,id){
//给全局变量赋值
colorId=id;
//清理其他颜色
$("#colors a").each(function(){
$(this).attr("class","changToWhite");
});
//先清理尺码 都变成不可点
$("#sizes a").each(function(){
$(this).attr("class","not-allow");
});
//点击变红
$(target).attr("class","changToRed");
//第一次尺寸默认变红
var flag=0;
//判断尺寸
<!--静态化填充数据 -->
<#list skuList as sku>
//判断sku中与当前选择颜色Id一样的,将获取所有的尺码
if(id=='${sku.colorId}'){
if(flag==0){//第一个尺寸,并获取第一个尺寸的价格
//第一次尺寸默认变红,例如海蓝色id=2的有尺寸 s,m,x,那么s位红,m,x为白
$("#"+'${sku.size}').attr("class","changToRed");
flag=1;
//填充数据
//巴巴价
$("#price").html('${sku.skuPrice}');
//市场价
$("#mprice").html('${sku.marketPrice}');
//运费
$("#fee").html('${sku.deliveFee}');
//库存
$("#stock").html('${sku.stockInventory}');
//skuid
skuId='${sku.id}';
//限购
buyLimit='${sku.skuUpperLimit}';
//默认给购买件数赋值为1
$("#num").val(1);
}else{
//非第一次尺寸默认变白,例如海蓝色id=2的有尺寸 s,m,x,那么s位红,m,x为白
$("#"+'${sku.size}').attr("class","changToWhite");
}
}
</#list>
}
//点击选择颜色id为尺码s,m,l...
function sizeToRed(target,id){
//先清理尺码 都变成不可点
//如果当前是不可点的不能点
var cc=$(target).attr("class");
if(cc=="not-allow"){
return;
}
$("#sizes a").each(function(){
var c=$(this).attr("class");
//排除了不开点的后,其余的都变白
if(c!="not-allow"){
$(this).attr("class","changToWhite");
}
});
//当前的变红
$(target).attr("class","changToRed");
<!--静态化填充数据 -->
<#list skuList as sku >
//判断sku中与当前选择颜色Id一样的,将获取所有的尺码
if(colorId=='${sku.colorId}'&&id=='${sku.size}'){
//填充数据
//巴巴价
$("#price").html('${sku.skuPrice}');
//市场价
$("#mprice").html('${sku.marketPrice}');
//运费
$("#fee").html('${sku.deliveFee}');
//库存
$("#stock").html('${sku.stockInventory}');
//skuid
skuId='${sku.id}';
//限购
buyLimit='${sku.skuUpperLimit}';
//默认给购买件数赋值为1
$("#num").val(1);
}
</#list>
}
//加入购物车
function addCart(){
alert("添加购物车成功!");
}
//立即购买
function buy(){
window.location.href='cart.jsp';
//skuId productId 件数 限购
}
</script>
</head>
<body>
<div class="w ofc mt">
<div class="l">
<div class="showPro">
<div class="big">
<a id="showImg" class="cloud-zoom" href="${product.img.allUrl }"
rel="adjustX:10,adjustY:-1"><img alt=""
src="${product.img.allUrl }"></a>
</div>
</div>
</div>
<div class="r" style="width: 640px">
<ul class="uls form">
<!--静态化填充数据 -->
<li><h2>${product.name }</h2></li>
<li><label>巴 巴 价:</label>
<span class="word"><b class="f14 red mr" id="price">¥128.00</b>(市场价:<del id="mprice">¥150.00</del>)</span></li>
<li><label>商品评价:</label>
<span class="word"> <span class="val_no val3d4" title="4分">4分 </span> <var class="blue">(已有888人评价)</var>
</span> </li>
<li><label>运 费:</label><span class="word" id="fee">10元</span></li>
<li><label>库 存:</label><span class="word" id="stock">100</span><span class="word">件</span></li>
<li><label>选择颜色:</label>
<div id="colors" class="pre spec">
<!--静态化填充数据 -->
<#list colors as color>
<a onclick="colorToRed(this,${color.id })" href="javascript:void(0)" title="${color.name }" class="changToWhite">
<img width="25" height="25" data-img="1" src="/res/img/pic/ppp00.jpg" alt="${color.name }">
<i>${color.name}</i>
</a>
</#list>
</div></li>
<li id="sizes"><label>尺 码:</label> <a href="javascript:void(0)"
class="not-allow" onclick="sizeToRed(this,'S')" id="S">S</a> <a
href="javascript:void(0)" class="not-allow"
onclick="sizeToRed(this,'M')" id="M">M</a> <a
href="javascript:void(0)" class="not-allow"
onclick="sizeToRed(this,'L')" id="L">L</a> <a
href="javascript:void(0)" class="not-allow"
onclick="sizeToRed(this,'XL')" id="XL">XL</a> <a
href="javascript:void(0)" class="not-allow"
onclick="sizeToRed(this,'XXL')" id="XXL">XXL</a></li>
<li><label>我 要 买:</label>
<a id="sub" class="inb arr" style="border: 1px solid #919191; width: 10px; height: 10px; line-height: 10px; text-align: center;"
title="减" href="javascript:void(0);">-</a>
<input id="num" type="text" value="1" name="" size="1" readonly="readonly">
<a id="add" class="inb arr" style="border: 1px solid #919191; width: 10px; height: 10px; line-height: 10px; text-align: center;"
title="加" href="javascript:void(0);">+</a>
</li>
<li class="submit"><input type="button" value="" class="hand btn138x40" onclick="buy();" />
<input type="button" value="" class="hand btn138x40b" onclick="addCart()" /></li>
</ul>
</div>
</div>
</body>