Freemarker商品詳情頁靜態化服務調用處理


---------------------------------------------------------------------------------------------

[版權申明:本文系作者原創,轉載請注明出處] 

文章出處:http://blog.csdn.net/sdksdk0/article/details/53151462

作者:朱培      ID:sdksdk0     

--------------------------------------------------------------------------------------------

最近在做一個移動電子商城的項目,在商品詳情頁處理這里處理的時候,因為我項目基本上都是用的jsp來寫的頁面,但是對於一個大型的購物網站來說,要解決掉速度的問題,所以需要把jsp換成html,這里我們可以使用Freemarker模板引擎來把jsp換成html供用戶來訪問.本文主要介紹的是如何使用Freemarker模板引擎來構建商品詳情頁,以及使用 CXF 做 webservice 發布服務,供后台添加商品時自動發布html網頁。使用的是maven+SSM框架

 

一、FreeMarker

FreeMarker模板文件主要由如下4個部分組成:

1,文本:直接輸出的部分 
2,注釋:<#-- ... -->格式部分,不會輸出 
3,插值:即${...}或#{...}格式的部分,將使用數據模型中的部分替代輸出 
4,FTL指令:FreeMarker指定,和HTML標記類似,名字前加#予以區分,不會輸出

 

關於FreeMarker的語法使用等這里不再重復說明,有需要的朋友可以自行查閱相關資料。

 

步驟:1,在core項目的resource文件下新建:productDetail.ftl文件,放在cn.tf.ecps.ftl目錄下。

關鍵代碼內容如下:就是通過FreeMarker的語法進行取值。

 

<div class="r wr">
		<div class="product">
        	<h2>${item.itemName }<span class="gray f14">${item.promotion }</span></h2>
			<div class="showPro">
				<div class="big"><a id="showImg" class="cloud-zoom" href="${file_path }${item.imgs}" rel="adjustX:10,adjustY:-1"><img title="optional title display" alt="" src="${file_path }${item.imgs}"></a></div>
				<div class="small">
					<span class="smallL" title="向左"> </span>
					<div class="smallBox">
						<div class="smallList">
							<a class="cloud-zoom-gallery here" title="red" href="${file_path }${item.imgs}" rel="useZoom: 'showImg', smallImage: '${file_path }${item.imgs}'"><img alt="thumbnail 1" src="${file_path }${item.imgs}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${file_path }${item.imgs}" rel="useZoom: 'showImg', smallImage: '${file_path }${item.imgs}'"><img alt="thumbnail 2" src="${file_path }${item.imgs}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${file_path }${item.imgs}" rel="useZoom: 'showImg', smallImage: '${file_path }${item.imgs}'"><img alt="thumbnail 3" src="${file_path }${item.imgs}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${file_path }${item.imgs}" rel="useZoom: 'showImg', smallImage: '${file_path }${item.imgs}'"><img alt="thumbnail 4" src="${file_path }${item.imgs}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${file_path }${item.imgs}" rel="useZoom: 'showImg', smallImage: '${file_path }${item.imgs}'"><img alt="thumbnail 5" src="${file_path }${item.imgs}"></a>
						</div>
					</div>
					<span class="smallR" title="向右"> </span>
				</div>
				<div class="share mt">
	
					<div id="ecpsShareIcon">
						<div class="iconSmall iconRight">
							<span>分享到:</span><a href="javascript:void(0);" target="_blank" class="sinawb" title="分享到新浪微博"></a><a href="javascript:void(0);" target="_blank" class="qqwb" title="分享到騰訊微博"></a><a href="javascript:void(0);" target="_blank" class="renren" title="分享到人人網"></a><a href="javascript:void(0);" target="_blank" class="qqzone" title="分享到QQ空間"></a><a href="javascript:void(0);" target="_blank" class="sohuwb" title="分享到搜狐微博"></a><a href="javascript:void(0);" class="copy" title="復制鏈接">復制鏈接</a>
						</div>
					</div>
				</div>
			</div>

			<form method="post" action="" name="" class="infor">
				<ul class="uls form">
				
				<li><label>移 動 價:</label><span class="word"><b id="skuPrice" class="f14 red mr">¥3999.00</b>(市場價:<del id="marketPrice">¥5789.00</del>)</span></li>
				<li><label>商品編號:</label><span class="word">${item.itemNo }</span></li>
				<li><label>商品評價:</label><span class="word"><span class="val_no val3d4" title="4分">4分</span><var class="blue">(已有17人評價)</var></span></li>
				<li><label>運  費:</label><span class="word">包郵    <a href="javascript:void(0);" class="blue">配送區域</a></span></li>
				<li><label>庫  存:</label><span id="stockState" class="word">有貨</span></li>
				<li><label>支付方式:</label><div class="pre word p16x16">
					<span title="網銀支付" class="bank">網銀支付</span>
					<span title="支付寶" class="pay">支付寶</span>
					<span title="手機支付" class="moblie">手機支付</span>
				</div></li>
				</ul>
				<div class="box_orange">
					<ul class="uls form">
					<li><label>規  格:</label><div class="pre spec">
					<#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>	
					</div></li>
 <li><label>我 要 買:</label><a href="javascript:void(0);" class="inb sub"></a><input readonly type="text" name="" value="1" class="num" size="3" /><a href="javascript:void(0);" class="inb add"></a><em id="sub_add_msg" class="red"></em></li><li class="submit"><input id="buyNow" type="button" value="" class="hand btn138x40" onclick="buy();"/><input id="addMyCart" type="button" value="" class="hand btn138x40b" onclick="addCart()"/><a href="#" title="加入收藏" class="inb fav">加入收藏</a></li></ul></div></form></div>


2、FMUtils文件

 

在/src/main/java/目錄中新建一個util文件,這是用來處理的一個工具類。

 

public class FMutil {
	
	/**
	 * 
	 * @param ftlName:模板名字
	 * @param fileName:生成的html的名字
	 * @param map:數據,在freemarket模板中取數據都使用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(), "/cn/tf/ecps/ftl");
		//獲得包的模板
		Template template = config.getTemplate(ftlName);
		//指定文件輸出的路徑
		String path = "E:/myeclipse_work/ECPS/ecps-parent/ecps-portal/src/main/webapp/html";
		//定義輸出流,注意的必須指定編碼
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(path+"/"+fileName)),"UTF-8"));
		//生成模板
		template.process(map, writer);
	}
}


3、測試

 

 

@Autowired
	private EbItemService itemService;

	@Test
	public void testGeneraHtml() throws Exception {
		Map<String,Object>  map=new HashMap<String,Object> ();
		EbItem item=itemService.selectItemDetailById(3080);
		map.put("item", item);
		
		map.put("path", ECPSUtil.readProp("portal_path"));
		map.put("file_path", ECPSUtil.readProp("FILE_PATH"));
		FMutil fm=new FMutil();

	     fm.ouputFile("productDetail.ftl", item.getItemId()+".html", map);
	
	}
	


這個時候我們就可以看到頁面效果出來了,在我們設置好的html目錄下:就可以找到生成的html文件3080.html了

 


 

 

當然,在這里提一句的是,這個項目非常復雜,我只是簡要的介紹一下使用FreeMarker的流程,而不是要介紹怎么做這個詳情頁最小單元的處理。

二、CXF服務調用

我們在做完這個模板處理之后,記u需要后台通過添加商品之后就可以將這個頁面生成出來,例如我后台有10萬個商品,那么我就需要生成10萬個靜態的html頁面保存在我的html文件服務器上面。

例如我這個后台,點擊發布按鈕之后,就可以自動生成一個html文件,把商品下相關信息保存在那個html中,每次更新商品時重新點擊發布就可以了,非常方便。


 

那么我們想要點擊發布按鈕之后就要生成代碼,自然需要我們的FreeMarker了,在真實生產環境中,都是分布式的,不在同一台機器上面,所以這就涉及到了我們的webService調用了。這里使用的是appach的cxf來處理。

下載地址:http://cxf.apache.org/download.html

 

1、新建一個ws的接口類:EbWSItemService,這里的接口我使用了md5加密加鹽處理。

 

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

}


實現其方法

 

 

@Service
public class EbWSItemServiceImpl  implements EbWSItemService {

	@Autowired
	private EbItemService itemService;
	
	
	public String publishItem(Long itemId, String password) {
		String isOK="success";
		
		String wsPass=GetMD5.getMD5(itemId);
		if(StringUtils.equals(password, wsPass)){
			//發布
			Map<String,Object>  map=new HashMap<String,Object> ();
			EbItem item=itemService.selectItemDetailById(itemId);
			map.put("item", item);
			
			map.put("path", ECPSUtil.readProp("portal_path"));
			map.put("file_path", ECPSUtil.readProp("FILE_PATH"));
			FMutil fm=new FMutil();
			try {
				fm.ouputFile("productDetail.ftl", item.getItemId()+".html", map);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			isOK="fail";
		}
		
		return isOK;
	}
}



 

屬性文件內容為:ecps.properties

 

FILE_PATH=http://localhost:8080/ecps-file

#操作類型
AUDIT_ITEM_TYPE=\u5546\u54C1\u5BA1\u6838
show_item_type=\u5546\u54C1\u4E0A\u4E0B\u67B6

portal_path=http://localhost:8080/ecps-portal

#接口加密
slat=xvzbnxsd^&&*)(*()kfmv4165323DGHSBJ



 

 

 

2、在項目中新建一個文件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" />
	<!-- 
		webservice服務地址:http://localhost:8080/ecps-portal/[url-patten]/address
		serviceClass:服務接口類
		jaxws:serviceBean:服務接口的實現類
		
	 -->
	<jaxws:server id="publishItem" address="/publishItem" serviceClass="cn.tf.ecps.ws.service.EbWSItemService">
		<jaxws:serviceBean>
			<bean class="cn.tf.ecps.ws.service.impl.EbWSItemServiceImpl"></bean>
		</jaxws:serviceBean>
	</jaxws:server>
	
</beans>

 

3、在前台工程的web.xml中進行配置

 

<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>

 

 

4、運行tomcat,通過鏈接訪問:

 


里面就是一個wsdl文件。我們都知道wsdl都是從下往上讀的,所以這里需要調用EbWSItemServiceService


 

發布服務之后我們需要使用這個cxf來生成java代碼:

wsdl2java -d . -p cn.tf.ecps.stub http://localhost:8080/ecps-portal/services/publishItem?wsdl


生成好之后,將生成好的代碼復制進你的工程即可。

 

然后在我們的port工程中,對service進行處理:

 

//調用服務
	public String publishItem(Long itemId, String password) {
		//創建服務訪問點的集合
		EbWSItemServiceService  itemServiceService=new EbWSItemServiceService();
		//獲得服務端的接口,通過服務訪問點的name在前面加上get這個方法就是獲得webService服務的接口方法
		EbWSItemService service = itemServiceService.getEbWSItemServicePort();
		//調用webService的發布方法
		return service.publishItem(itemId, password);
	}


最后在controller中調用那個這個service就可以了

 

 

//調用服務
	@RequestMapping("/publish.do")
	public void publish(Long itemId,PrintWriter out){
		String wsPass=GetMD5.getMD5(itemId);
		String result = null;
		try {
			result = itemService.publishItem(itemId,wsPass);
		} catch (Exception e) {
			e.printStackTrace();
		}
		out.write(result);
	
	}


這樣整個過程就完成了。

 

 


這里值得一提的是如果你發布的服務是用的localhost:8080,那么在前台工程也要用localhost:8080,否則會報錯,我就是因為這個原因折騰了幾個小時,原因是跨域問題。

可以通過前台來看到生成好的html頁面。

 

 

項目地址:https://github.com/sdksdk0/ECPS

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM