精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-27
做门户网站有大量的页面 页面数据之多 每次请求都要查询数据库操作 性能 差 速度也慢的不得了 使用freemark生成静态页面
FreeMarker 是一个用Java编写的模板引擎,主要用来生成HTML Web页面,特别是基于MVC模式的应用程序。虽然FreeMarker具有一些编程的能力,但不像PHP,通常由Java程序准备要显示的数据,由 FreeMarker模板生成页面。 FreeMarker可以作为Web应用框架一个组件,但它与容器无关,在非Web应用程序环境也能工作的很好。 FreeMarker适合作为MVC的视图组件,还能在模板中使用JSP标记库。 ftl模板 + Map数据模型 = 输出html首先编写使ftl模板可以生成html的代码 必需导入freemark包 public class CreateHTML { private Configuration freemarker_cfg = null; // private String sGeneFilePath = null; // private String sGeneFileName = null; // private String sTempPlateFilePath = null; /** * 创建多级目录 * * @param path * String * @return boolean 是否成功 */ private boolean creatDirs(String path) { File aFile = new File(path); if (!aFile.exists()) { return aFile.mkdirs(); } else { return true; } } /** * 生成静态文件. * * @param templateFileName * 模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl" * @param propMap * 用于处理模板的属性Object映射 * @param htmlFilePath * 要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/" * @param htmlFileName * 要生成的文件名,例如 "1.htm" * @param templateFilePath * 模板路径 * @return boolean true代表生成文件成功 */ @SuppressWarnings("unchecked") public void geneHtmlFile(String templateFileName, Map propMap, String htmlFilePath, String htmlFileName, String templateFilePath) { try { Template t = this.getFreeMarkerCFG(templateFilePath).getTemplate( templateFileName); // 如果根路径存在,则递归创建子目录 this.creatDirs(htmlFilePath); File afile = new File(htmlFilePath + "/" + htmlFileName); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(afile))); t.process(propMap, out); out.flush(); out.close(); } catch (TemplateException e) { System.out.print(e.getMessage()); } catch (IOException e) { System.out.print(e.getMessage()); } catch (Exception e) { System.out.print(e.getMessage()); } } /** * * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取. * * @param templateFilePath * 获取模板路径 * @return Configuration 返回freemaker的配置属性 * @throws Exception */ private Configuration getFreeMarkerCFG(String templateFilePath) throws Exception { if (null == this.freemarker_cfg) { this.freemarker_cfg = new Configuration(); try { this.freemarker_cfg.setDirectoryForTemplateLoading(new File( templateFilePath)); } catch (Exception ex) { throw ex; } } return this.freemarker_cfg; } }
写一个定时器 定时生成静态页面
public class ContextListener implements ServletContextListener { private static final long serialVersionUID = 1L; private Timer timer = null; public void contextDestroyed(ServletContextEvent event) { timer.cancel(); event.getServletContext().log("定时器销毁"); } public void contextInitialized(ServletContextEvent event) { timer = new Timer(true); event.getServletContext().log("定时器已启动"); // 6000 参数单位为毫秒 自动调用IndexTask类中的run方法 timer.schedule(new IndexTask(event), 0, 6000); } } 调用定时器中的程序 查询数据生成静态页面 public class IndexTask extends TimerTask { ServletContextEvent context; WebApplicationContext wac; BlogService blogService; public IndexTask(ServletContextEvent event) { context = event; ServletContext application = context.getServletContext(); wac = WebApplicationContextUtils.getWebApplicationContext(application); } public void run() { try { //这里使用spring框架 blogService = (BlogService) wac.getBean("blogService"); Map root = new HashMap(); // 會員積分排行 查询数据存放在root Map中 ftl模板可以使用userAlbum //blogService.findByAlbum是写好的dao查询方法 root.put("userAlbum", blogService.findByAlbum( "queryTopUserByscore")); CreateHTML chtml = new CreateHTML(); chtml.geneHtmlFile("index.ftl", root, context.getServletContext() .getRealPath("/"), "index.html", context .getServletContext().getRealPath( "/WEB-INF/templates")); } catch (Exception e) { e.printStackTrace(); } finally { } }
然后写ftl模板 我把ftl存放在/WEB-INF/templates/ 目录下 新建index.ftl 写要迭代的数据 比如我这里存放的数据名称为userAlbum
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <div id="Layer4_right" class="left"> <div id="Layer4_right_bg1"> <span>个人·博客</span> <a href="/album/searchAlbum.action>更多>></a> </div> <div id="Layer4_right_content"> 这里使用#list 迭代数据和foreach差不多 使用了#if #else判断数据的长度 <div id="Layer4_right_content_Gray"> <ul> <#list userAlbum as pro> <li> <a href="/album/searchAlbumDesc.action?shnAlbum.albumid=${pro.albumid!}"> <img src="/upload/photo/smallimage/${pro.images!}" alt="相片" width="102" height="101" /> </a> <span>专辑:<a href="/album/searchAlbum.action?albumid=${pro.albumid!}"> <#if (pro.title?length gt 5)>${pro.title[0..3]!}..<#else>${pro.title!}</#if> </a> </li> </#list> </ul> </div> </div>
先来解释一下freemaker的基本语法了,
|
|
返回顶楼 | |
发表时间:2012-01-03
freemarker还是不错的,非要学一种模板语言的话,就它了
|
|
返回顶楼 | |
发表时间:2012-01-04
zhouxingfu520 写道
做门户网站有大量的页面 页面数据之多 每次请求都要查询数据库操作 性能 差 速度也慢的不得了 使用freemark生成静态页面
FreeMarker 是一个用Java编写的模板引擎,主要用来生成HTML Web页面,特别是基于MVC模式的应用程序。虽然FreeMarker具有一些编程的能力,但不像PHP,通常由Java程序准备要显示的数据,由 FreeMarker模板生成页面。 FreeMarker可以作为Web应用框架一个组件,但它与容器无关,在非Web应用程序环境也能工作的很好。 FreeMarker适合作为MVC的视图组件,还能在模板中使用JSP标记库。 ftl模板 + Map数据模型 = 输出html首先编写使ftl模板可以生成html的代码 必需导入freemark包 public class CreateHTML { private Configuration freemarker_cfg = null; // private String sGeneFilePath = null; // private String sGeneFileName = null; // private String sTempPlateFilePath = null; /** * 创建多级目录 * * @param path * String * @return boolean 是否成功 */ private boolean creatDirs(String path) { File aFile = new File(path); if (!aFile.exists()) { return aFile.mkdirs(); } else { return true; } } /** * 生成静态文件. * * @param templateFileName * 模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl" * @param propMap * 用于处理模板的属性Object映射 * @param htmlFilePath * 要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/" * @param htmlFileName * 要生成的文件名,例如 "1.htm" * @param templateFilePath * 模板路径 * @return boolean true代表生成文件成功 */ @SuppressWarnings("unchecked") public void geneHtmlFile(String templateFileName, Map propMap, String htmlFilePath, String htmlFileName, String templateFilePath) { try { Template t = this.getFreeMarkerCFG(templateFilePath).getTemplate( templateFileName); // 如果根路径存在,则递归创建子目录 this.creatDirs(htmlFilePath); File afile = new File(htmlFilePath + "/" + htmlFileName); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(afile))); t.process(propMap, out); out.flush(); out.close(); } catch (TemplateException e) { System.out.print(e.getMessage()); } catch (IOException e) { System.out.print(e.getMessage()); } catch (Exception e) { System.out.print(e.getMessage()); } } /** * * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取. * * @param templateFilePath * 获取模板路径 * @return Configuration 返回freemaker的配置属性 * @throws Exception */ private Configuration getFreeMarkerCFG(String templateFilePath) throws Exception { if (null == this.freemarker_cfg) { this.freemarker_cfg = new Configuration(); try { this.freemarker_cfg.setDirectoryForTemplateLoading(new File( templateFilePath)); } catch (Exception ex) { throw ex; } } return this.freemarker_cfg; } }
写一个定时器 定时生成静态页面
public class ContextListener implements ServletContextListener { private static final long serialVersionUID = 1L; private Timer timer = null; public void contextDestroyed(ServletContextEvent event) { timer.cancel(); event.getServletContext().log("定时器销毁"); } public void contextInitialized(ServletContextEvent event) { timer = new Timer(true); event.getServletContext().log("定时器已启动"); // 6000 参数单位为毫秒 自动调用IndexTask类中的run方法 timer.schedule(new IndexTask(event), 0, 6000); } } 调用定时器中的程序 查询数据生成静态页面 public class IndexTask extends TimerTask { ServletContextEvent context; WebApplicationContext wac; BlogService blogService; public IndexTask(ServletContextEvent event) { context = event; ServletContext application = context.getServletContext(); wac = WebApplicationContextUtils.getWebApplicationContext(application); } public void run() { try { //这里使用spring框架 blogService = (BlogService) wac.getBean("blogService"); Map root = new HashMap(); // 會員積分排行 查询数据存放在root Map中 ftl模板可以使用userAlbum //blogService.findByAlbum是写好的dao查询方法 root.put("userAlbum", blogService.findByAlbum( "queryTopUserByscore")); CreateHTML chtml = new CreateHTML(); chtml.geneHtmlFile("index.ftl", root, context.getServletContext() .getRealPath("/"), "index.html", context .getServletContext().getRealPath( "/WEB-INF/templates")); } catch (Exception e) { e.printStackTrace(); } finally { } }
然后写ftl模板 我把ftl存放在/WEB-INF/templates/ 目录下 新建index.ftl 写要迭代的数据 比如我这里存放的数据名称为userAlbum
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <div id="Layer4_right" class="left"> <div id="Layer4_right_bg1"> <span>个人·博客</span> <a href="/album/searchAlbum.action>更多>></a> </div> <div id="Layer4_right_content"> 这里使用#list 迭代数据和foreach差不多 使用了#if #else判断数据的长度 <div id="Layer4_right_content_Gray"> <ul> <#list userAlbum as pro> <li> <a href="/album/searchAlbumDesc.action?shnAlbum.albumid=${pro.albumid!}"> <img src="/upload/photo/smallimage/${pro.images!}" alt="相片" width="102" height="101" /> </a> <span>专辑:<a href="/album/searchAlbum.action?albumid=${pro.albumid!}"> <#if (pro.title?length gt 5)>${pro.title[0..3]!}..<#else>${pro.title!}</#if> </a> </li> </#list> </ul> </div> </div>
先来解释一下freemaker的基本语法了,
|
|
返回顶楼 | |
发表时间:2012-01-05
最后修改:2012-01-05
感觉这样灵活性还不是很大,目木有没有这样的一种技术或是框架呢?
就像一个超级过滤器一样, 工作原理是这样的, 1. 用户访问某个页面: http://xxx.com/a/b/c.jsp?d=1&e=2 2. 过滤器(根据一定得算法得到文件名)去后面查找有没有生成过这个页面的静态文件,或是有没有过期, 没有或是过期都重新生成 3. 直接dispatcher到这个静态页面 这样应该需要一个比较强大的规则管理机制和页面过期检查机制, 动态部分,比如库存/运费这种, 可以用js调用解决 我想这样的好处是, 编程的时候(不论是jsp还是bean)灵活性大增, 不用考虑太多 |
|
返回顶楼 | |
发表时间:2012-01-05
我也觉得freemark用起来不是很灵活,项目本身就复杂,还要时不时的注意编写静态化代码,感觉带来的收益还不如我伪静态+负载均衡实在。
|
|
返回顶楼 | |
发表时间:2012-01-08
qiaojoy99 写道 我也觉得freemark用起来不是很灵活,项目本身就复杂,还要时不时的注意编写静态化代码,感觉带来的收益还不如我伪静态+负载均衡实在。
你说的和freemarker是两码事。完全的两码事。 |
|
返回顶楼 | |
发表时间:2012-01-10
做cms模板来说确实是不太灵活,除非自己进行二次开发写出一套自定义标记来。
比如: <tag:list name="item" pagesize="20" order ="pubdate" orderby="asc"> <li> ${item.title}</li> </tag:list> 通常网页的模板标签就是由各样的标记来生成的 可以在dw里开发些自定义的控件来实现这些 标记 而且大的网站都有什么生成服务器,分发服务器,CDN.... |
|
返回顶楼 | |
发表时间:2012-02-20
有类似你要求的: oscache.
做为前端过滤器使用 sanshizi 写道 感觉这样灵活性还不是很大,目木有没有这样的一种技术或是框架呢?
就像一个超级过滤器一样, 工作原理是这样的, 1. 用户访问某个页面: http://xxx.com/a/b/c.jsp?d=1&e=2 2. 过滤器(根据一定得算法得到文件名)去后面查找有没有生成过这个页面的静态文件,或是有没有过期, 没有或是过期都重新生成 3. 直接dispatcher到这个静态页面 这样应该需要一个比较强大的规则管理机制和页面过期检查机制, 动态部分,比如库存/运费这种, 可以用js调用解决 我想这样的好处是, 编程的时候(不论是jsp还是bean)灵活性大增, 不用考虑太多 |
|
返回顶楼 | |
浏览 17519 次