首先将原先接受action返回结果的index.jsp分割为3个部分,top.jsp,body.jsp,bottom.jsp,以便分别通过freemaker模板生成各个部分,并进行include。
本文以生成 body.jsp为例,讲解整个流程。
第一步、将原先网站首页主体的动态body.jsp转换为body.ftl:
转换结果如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <#macro indexTopicList indexTopic titleSize showDate=true hasH=false hasDt=true showDot=true df="MM/dd" divId="" hrefClz=""> <div ${(divId=="")?string("","id='${divId}'")}> <#if hasH> <#nested/> </#if> <dl> <#if hasDt> <dt><#nested/></dt> </#if> <#list indexTopic.topics as topic> <dd> <a title="${topic.title}" href="topic/${topic.id}" ${(hrefClz=="")?string("","class='${hrefClz}'")}> <#if showDate>[${(topic.publishDate)?string("${df}")}]</#if> <#if topic.title?length gt titleSize> ${topic.title[0..titleSize]}<#if showDot>...</#if> <#else> ${topic.title} </#if> </a> </dd> </#list> </dl> </div> </#macro> <div id="content"> <div id="content_con"> <div id="xiaoxun"></div> <div id="notice_rollpic"> <@indexTopicList indexTopic=ts["1"] titleSize=12 divId="notice" hrefClz="index_link"> <span><a href="channel/${ts["1"].cid}" class="index_title_href">${ts["1"].cname}</a></span> </@indexTopicList> <div id="rollpic"> <div id="rollCaption"><span></span></div> <div id="rollPager"></div> <#list pics as pic> <a href="${pic.linkUrl}" title="${pic.title}"><img src="<%=request.getContextPath()%>/resources/indexPic/${pic.newName}" border="0"/></a> </#list> </div> </div> <div id="split_line"></div> <div id="xwgk_xxgk"> <@indexTopicList indexTopic=ts["2"] hasH=true hasDt=false titleSize=37 divId="xwgk" hrefClz="index_link"> <h3><a href="channel/${ts["2"].cid}" class="index_title_href">${ts["2"].cname}</a></h3> <div id="xwgk_bg"></div> </@indexTopicList> <div id="xxgk"> <h3><a href="channel/7" class="index_title_href">学校概况</a></h3> <div id="xxgk_bg"></div> ${xxgk.summary[0..360]} </div> </div> <div id="hdjx_jyky"> <@indexTopicList indexTopic=ts["3"] titleSize=31 divId="hdjx" hrefClz="index_link"> <span class="t_title">${ts["3"].cname}</span><span class="more"><a href="channel/${ts['3'].cid}">更多</a></span> </@indexTopicList> <@indexTopicList indexTopic=ts["4"] titleSize=31 divId="jyky" hrefClz="index_link"> <span class="t_title">${ts["4"].cname}</span><span class="more"><a href="channel/${ts['4'].cid}">更多</a></span> </@indexTopicList> </div> <div id="chief_keyword"> <div> <#list keywords as kw> <span class="keyword" href="keyword/${kw.name}">${kw.name}</span> </#list> </div> </div> </div> </div>
将body.ftl等模板文件,放在项目的classpath的resources文件夹中,以便后续调用。
步骤二、写模板转静态jsp的接口和实现,如下:
package org.konghao.cms.service; public interface IIndexService { public void generateTop(); public void generateBottom(); public void generateBody(); }
package org.konghao.cms.service; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.inject.Inject; import org.directwebremoting.ui.servlet.BaseUtilHandler; import org.konghao.basic.model.SystemContext; import org.konghao.basic.util.FreemarkerUtil; import org.konghao.basic.util.PropertiesUtil; import org.konghao.cms.model.BaseInfo; import org.konghao.cms.model.Channel; import org.konghao.cms.model.ChannelType; import org.konghao.cms.model.IndexTopic; import org.konghao.cms.model.Topic; import org.konghao.cms.web.BaseInfoUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("indexService") public class IndexService implements IIndexService { private String outPath; private FreemarkerUtil util; @Autowired(required=true) public IndexService(String ftlPath, String outPath) { super(); if(util==null) { this.outPath = outPath; util = FreemarkerUtil.getInstance(ftlPath); } } private IChannelService channelService; private ITopicService topicService; private IIndexPicService indexPicService; private IKeywordService keyworkService; public IKeywordService getKeyworkService() { return keyworkService; } @Inject public void setKeyworkService(IKeywordService keyworkService) { this.keyworkService = keyworkService; } public IIndexPicService getIndexPicService() { return indexPicService; } @Inject public void setIndexPicService(IIndexPicService indexPicService) { this.indexPicService = indexPicService; } public ITopicService getTopicService() { return topicService; } @Inject public void setTopicService(ITopicService topicService) { this.topicService = topicService; } public IChannelService getChannelService() { return channelService; } @Inject public void setChannelService(IChannelService channelService) { this.channelService = channelService; } @Override public void generateTop() { System.out.println("=============重新生成了顶部信息===================="); List<Channel> cs = channelService.listTopNavChannel(); Map<String,Object> root = new HashMap<String,Object>(); root.put("navs", cs); root.put("baseInfo", BaseInfoUtil.getInstacne().read()); String outfile = SystemContext.getRealPath()+outPath+"/top.jsp"; util.fprint(root, "/top.ftl", outfile); } @Override public void generateBottom() { System.out.println("=============重新生成了底部信息===================="); Map<String,Object> root = new HashMap<String,Object>(); root.put("baseInfo", BaseInfoUtil.getInstacne().read()); String outfile = SystemContext.getRealPath()+outPath+"/bottom.jsp"; util.fprint(root, "/bottom.ftl", outfile); } @Override public void generateBody() { System.out.println("=========重新生成首页的内容信息=============="); //1、获取所有的首页栏目 List<Channel> cs = channelService.listAllIndexChannel(ChannelType.TOPIC_LIST); //2、根据首页栏目创建相应的IndexTopic对象 //加载indexChannel.properties Properties prop = PropertiesUtil.getInstance().load("indexChannel"); Map<String,IndexTopic> topics = new HashMap<String, IndexTopic>(); for(Channel c:cs) { int cid = c.getId(); String[] xs = prop.getProperty(cid+"").split("_"); String order = xs[0]; int num = Integer.parseInt(xs[1]); IndexTopic it = new IndexTopic(); it.setCid(cid); it.setCname(c.getName()); List<Topic> tops = topicService.listTopicByChannelAndNumber(cid, num); // System.out.println(cid+"--"+tops); it.setTopics(tops); topics.put(order, it); } String outfile = SystemContext.getRealPath()+outPath+"/body.jsp"; //3、更新首页图片 BaseInfo bi = BaseInfoUtil.getInstacne().read(); int picnum = bi.getIndexPicNumber(); Map<String,Object> root = new HashMap<String,Object>(); root.put("ts", topics); root.put("pics", indexPicService.listIndexPicByNum(picnum)); root.put("keywords", keyworkService.getMaxTimesKeyword(12)); root.put("xxgk", topicService.loadLastedTopicByColumn(7)); util.fprint(root, "/body.ftl", outfile); } }
<div id="content"> <div id="content_con"> <div id="xiaoxun"></div> <div id="notice_rollpic"> <div id='notice'> <dl> <dt> <span><a href="channel/10" class="index_title_href">校园快讯</a></span> </dt> <dd> <a title="校园快讯4" href="topic/28" class='index_link'> [10/21] 校园快讯4 </a> </dd> <dd> <a title="校园快讯测试3" href="topic/37" class='index_link'> [10/21] 校园快讯测试3 </a> </dd> <dd> <a title="校园快讯测试2" href="topic/21" class='index_link'> [10/21] 校园快讯测试2 </a> </dd> <dd> <a title="校园快讯测试1" href="topic/9" class='index_link'> [10/21] 校园快讯测试1 </a> </dd> <dd> <a title="校园快讯测试5" href="topic/33" class='index_link'> [10/21] 校园快讯测试5 </a> </dd> <dd> <a title="文章测试2" href="topic/18" class='index_link'> [10/21] 文章测试2 </a> </dd> <dd> <a title="测试文章1" href="topic/14" class='index_link'> [10/21] 测试文章1 </a> </dd> <dd> <a title="测试图片" href="topic/3" class='index_link'> [10/21] 测试图片 </a> </dd> </dl> </div>
步骤三、将新生成的静态body.jsp,top.jsp,bottom.jsp按照原先index.jsp的分割顺序include到index.jsp首页jsp中。
片段如下:
index.jsp
<body> <jsp:include page="/jsp/template/top.jsp"/> <jsp:include page="/jsp/template/body.jsp"/> <jsp:include page="/jsp/template/bottom.jsp"/> </body>
在后台,每次更新新闻内容以后,就可以通过静态生成功能按钮调用静态生成Service。而用户访问首页每次刷新的时候也不必再去通过Control中去取数据库内容了。
而是直接访问生成的静态页面,静态页面中没有action的返回结果。速度大大提高!
【项目总结:波士顿东大校友会】使用freemaker实现前台页面静态化
原文地址:http://blog.csdn.net/aiwuzhiling/article/details/39294291