移动商城第十六篇【静态页面发布】


tags: 移动商城项目


移动商城第十六篇【静态化页面】

首先,我们要知道为什么使用静态化页面???

静态页面= 模版+数据

我们的单品页面会经常被访问到,而每次我们都是需要去访问数据库来查询具体的数据。这样很耗费性能

那么能不能不访问数据库就能够查询出数据的数据呢??

  • 这类似于我们数据库连接池这么一个概念,把连接都创建了,需要的时候就使用。

当用户访问单品页面的之前,我们就可以把页面静态化(模版+数据),那么用户访问被静态化的页面,也就是html就行了。这样一来,查看单品页就不用访问数据库了。。

那怎么使用呢??

将我们的单品页弄成是静态页:

我们的静态页到最后是变成HTML格式的,因此是不能用半点的JAVA语法的。因此要把动态的数据改成是freemaker所熟悉的语法来更替掉

常用的语法

使用frermarker语法 定义path的变量

<#assign path="http://localhost:8080/ecps-portal">
复制代码

这种不用改,我们只要将item传入map中就行了。

forEach和if标签都要修改

修改前:


  <c:forEach items="${item.ebSkus }" var="sku" varStatus="state">
                                    <c:choose>
                                        <c:when test="${state.index == 0 }">
                                            <a href="javascript:void(0);" class="here" skuId="${sku.skuId}">
                                                <c:forEach items="${sku.specList }" var="spec">
                                                    ${spec.specValue }
                                                </c:forEach>
                                            </a>
                                        </c:when>
                                        <c:otherwise>
                                            <a href="javascript:void(0);" skuId="${sku.skuId }">
                                                <c:forEach items="${sku.specList }" var="spec">
                                                    ${spec.specValue }
                                                </c:forEach>
                                            </a>
                                        </c:otherwise>
                                    </c:choose>

                                </c:forEach>
复制代码

修改后:

						<#list item.skuList as sku>
								<#if sku_index == 0>
									<a href="javascript:void(0);" class="here" skuId="${sku.skuId?c }">
										<#list sku.specList as spec>
											${spec.specValue }
										</#list>
									</a>
								
								<#else>
									<a href="javascript:void(0);" skuId="${sku.skuId?c }">
										<#list sku.specList as spec>
											${spec.specValue }
										</#list>
									</a>
								</#if>
							
						</#list>


复制代码

freemarker语法自动带有,号的数值类型,我们一般不使用。于是使用?c来格式化

skuId="${sku.skuId?c }
复制代码

时间的转换:

${sendTime?string("yyyy-MM-dd HH:mm:ss")}
复制代码

freemarker工具类



package com.rl.ecps.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class FMutil {
	
	/**
	 * 
	 * @param ftlName:模板名
	 * @param fileName:生成的html名字
	 * @param map 数据库中的数据
	 * @throws Exception
	 */
	public void ouputFile(String ftlName, String fileName,  Map<String, Object> map) throws Exception{
		//创建fm的配置
		Configuration config = new Configuration();
		//指定默认编码格式
		config.setDefaultEncoding("UTF-8");
		//设置模板的包路径
		config.setClassForTemplateLoading(this.getClass(), "/com/rl/ecps/ftl");
		//获得包的模板
		Template template = config.getTemplate(ftlName);
		//指定文件输出的路径
		String path = "X:\\Users\\ozc\\Desktop\\parent1\\portal\\src\\main\\webapp\\static";
		//定义输出流,注意的必须指定编码
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(path+"/"+fileName)),"UTF-8"));
		//生成模板
		template.process(map, writer);
	}
	
	
}

复制代码

测试


    @Test
    public void TestFreemarker() throws Exception {
        EbItem ebItem = itemService.selectItemDetail((long) 3100);

        Map map = new HashMap();
        map.put("item", ebItem);
        FMutil fMutil = new FMutil();
        fMutil.ouputFile("productDetail.ftl", ebItem.getItemId() + ".html", map);

    }

复制代码

最终生成我们的静态页面:

访问静态页面:

发布静态页面

我们上边是通过test的方式来生成我们的静态页面的。明显地,我们生成静态页面就不是在portal进行处理的。应该是交由console来进行处理的。

那现在问题来了,怎么将console处理后的页面交由到portal中呢??

  • console和portal是属于两台不同的机器的(IP地址是不同的)。是在不同的工作目录下的。

由于IP地址不同,是两台不同的机器,我们就可以想到webservice!

  • 由portal中发布服务,console进行调用,那么portal就能够有对应的静态页面了!

编写webService代码:


@WebService
public interface EbWSItemService {
	
	public String publishItem(Long itemId, String password) throws Exception;

}

复制代码

@Service
public class EbWSItemServiceImpl implements EbWSItemService {

	@Autowired
	private EbItemDao itemDao;
	
	public String publishItem(Long itemId, String password) throws Exception {
		String pass = ResourcesUtils.readProp("ws_pass");
		if(StringUtils.equals(password, pass)){
			EbItem item  = itemDao.selectItemDetail(itemId);
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("item", item);
			FMutil fm = new FMutil();
			fm.ouputFile("productDetail.ftl", item.getItemId()+".html", map);
			return "success";
		}else{
			return "pass_error";
		}
	}

}
复制代码

使用CXF框架将我们的webService服务在portal端发布

cxf-servlet.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:jaxws="http://cxf.apache.org/jaxws"
	xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd
            http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
            http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
	<!-- 引入CXF Bean定义如下,早期的版本中使用 -->
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	
	<!-- 
		address:
		http://localhost:8080/ecps-portal/[url-partten]/address
	 -->
	<jaxws:server id="publishItem" address="/publishItem" serviceClass="com.rl.ecps.webservice.EbWSItemService">
		<jaxws:serviceBean>
			<bean class="com.rl.ecps.webservice.EbWSItemServiceImpl"></bean>
		</jaxws:serviceBean>
	</jaxws:server>
</beans>

复制代码

portal端进行加载该配置文件:



    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>

        <!--加载cxf配置文件-->
        <param-value>classpath*:beans.xml,classpath*:cxf-servlet.xml</param-value>
    </context-param>


    <!--cxf的Servlet-->
    <servlet>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

复制代码

当访问portal端的services的时候,就可以看到服务进行发出去了!

使用IDEA的工具将WSDL地址转成是Java类

得出这么一堆对象

在service层调用这么一些对象(也就是portal发布的服务)



    public String publishItem(Long itemId, String password) throws Exception {

        EbWSItemServiceService itemServiceService = new EbWSItemServiceService();
        EbWSItemService ebWSItemServicePort = itemServiceService.getEbWSItemServicePort();
        return ebWSItemServicePort.publishItem(itemId, password);
    }


复制代码

controller调用service



    @RequestMapping("/publishItem.do")
    public void publishItem(Long itemId, PrintWriter out) throws Exception {
        String password = ResourcesUtils.readProp("ws_pass");
        String result = itemService.publishItem(itemId, password);
        out.write(result);
    }
复制代码

前台时候ajax进行调用:



        function publishItem(itemId) {
            $.ajax({
                url:"${path}/item/publishItem.do",
                type:"post",
                dataType:"text",
                data:{
                    itemId:itemId
                },
                success:function(responseText){
                    if(responseText == "success"){
                        alert("发布成功");
                    }else{
                        alert("密码错误");
                    }
                    tipHide("#importLoadDiv");
                },
                error:function(){
                    alert("系统错误");
                }
            })

        }
复制代码

这样一来,console是调用portal发布的webservice程序。那么生成的静态页面就是portal上的。

#总结 #

  • 使用静态化页面能够减少对数据库的访问,浏览速度会大大加快
  • 使用freemarker语法将JSTL的标签替换掉,再将后缀改成是ftl就行了。
    • 使用工具类将模版渲染成html类型
  • 由于前后端的分离,将模版渲染成html类型是在后端干的。但在访问的时候是在前台的工作目录上。
    • 问题就是怎么将后台生成的html页面发送给前台
    • 因为前台和后台的电脑是不一样的,IP地址也是不一样的。
  • 要使用到webservice,webservice能够调用远程的服务。
    • 在portal上发布远程的服务
    • console调用portal的服务,生成的数据就在portal上了。

如果您觉得这篇文章帮助到了您,可以给作者一点鼓励

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值