首先将原先接受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();
}
实现:将静态jsp生成到指定路径。
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);
}
}
生成的新的静态body.jsp片段如下:
<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>
然后分别生成top.jsp,bottom.jsp。
步骤三、将新生成的静态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的返回结果。速度大大提高!