JSP 生成静态页

xxp5693

贡献于2012-07-13

字数:8549 关键词: JSP Java开发

常见的分类信息首页,需读取至少六次数据库;其他子页面,五至十几次次不等。   在使用数据库连接池的情况下,Tomcat可以支撑的并发量也十分有限。系统资源主要消耗在两方面:   1、数据库操作,频繁的从数据库返回结果;   2、Tomcat解析JAVA文件。   将动态页面按一定规则创建一匹.html纯静态页面的过程,称之为生成静态页面。   优点   无须访问数据库,节省了最大的系统消耗。   Tomcat直接返回.html静态文件,无须解析JAVA文件,最大限度的提高效率。   安全,避免了非法传递参数所导致的错误。   缺点   生成的大量.html静态页面需要占用较多的硬盘空间。   失去了动态页面所具有交互性能。   运行稳定的动态页面是生成.html静态页面的前提。   起初,.html静态页面是通过系统频繁的访问(抓取)动态页面,得到运行结果,再而保存为.html档而来的.因此,抓取这一部分操作将是生成静态页面的核心;而如何尽可能减少抓取后的解析操作,取决于动态页面(例:Jsp页面);以何种规则保存这些.html静态页面、如何利用静态页面与用户交互等等也是避不可少的.归纳以下几点:   1、定义规则   绝大部分Jsp页面作用将不再是面对用户,而是供系统调用,得到运行结果,从而保存为.html档.因此,Jsp应该根据核心代码的规则,替换所有.jsp标签及连接.由.html代替。   2、路径   若.html静态页面太多,将不可避免的存放在不同的文件夹下。   在所有Jsp页面里指定以根目录开头的绝对路径,是解决办法之一。   3、交互性能   静态页面不可避免的失去了交互性能,例如:无法统计信息的阅读次数,无法得到Session信息等等.但也并非没有解决的办法,思路是将整张静态页面分割成若干张小页面,小页面依旧可以是.html静态页面,也可以是.Jsp动态页面.例如,可以嵌套某一零高度零宽度的.Jsp文件专门用作统计信息的阅读次数。   4、优化   若信息量比较大,.html静态页面占用硬盘容量也会随之增大.将静态页面共有的部分组织成一张新的.html页面,再令所有静态页面嵌套这样一个文件有助于降低页面体积.(注意该体积只能降低页面的文件大小,无助于提高访问效率)   5、风险   风险主要集中在生成静态页面的这个过程.网络异常可能导致返回的Jsp页面运行结果为空白、频繁读取可能导致Jsp页面未显示完整就保存为.html档等等,都是要考虑的问题。 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 给你一个我做着玩的CMS中的解析自定义模板标签的代码片段 总体思想就是自己定义一套标签 然后用正则解析模板后替换成最终数据 Java code package parser; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Vector; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.MatchResult; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.PatternMatcher; import org.apache.oro.text.regex.PatternMatcherInput; import org.apache.oro.text.regex.Perl5Compiler; import org.apache.oro.text.regex.Perl5Matcher; import vo.ListItem; import db.Conn1; import util.TDate; public class IndexParser{ private List bigtext=new Vector(); private String regex1="(\\{pannycms:list\\s+typeid=\\d+\\s+order=[a-zA-Z]+\\s+offset=\\d+\\s+length=\\d+\\s+ifpic=\\d\\s*\\}[^\\{]*\\{/pannycms:list\\})"; private String regex2="\\{pannycms:list\\s+typeid=(\\d+)\\s+order=([a-zA-Z]+)\\s+offset=(\\d+)\\s+length=(\\d+)\\s+ifpic=(\\d)\\s*\\}([^\\{]*)\\{/pannycms:list\\}"; private String regex3="(\\{pannycms:menulink\\s+typeid=(\\d+)\\s*/\\})"; private String regex4="(\\{pannycms:sectionurl\\s+typeid=(\\d+)\\s*/\\})"; public String parser(String template) { TDate td=new TDate(); //获取一个链接 Conn1 c=new Conn1(); //先把所有的列表部分装进list bigtext Perl5Compiler compiler=new Perl5Compiler(); Pattern pattern=null; try { pattern=compiler.compile(regex1,Perl5Compiler.CASE_INSENSITIVE_MASK); } catch (MalformedPatternException e) { // TODO Auto-generated catch block e.printStackTrace(); } PatternMatcher matcher=new Perl5Matcher(); PatternMatcherInput pmi=new PatternMatcherInput(template); while(matcher.contains(pmi,pattern)) { MatchResult result=matcher.getMatch(); //System.out.println(result.group(1)); bigtext.add(result.group(1)); for(String ss1:bigtext) { PatternMatcherInput pmi1=new PatternMatcherInput(ss1); ListItem lt=new ListItem(); Pattern pattern1=null; try { pattern1=compiler.compile(regex2,Perl5Compiler.CASE_INSENSITIVE_MASK); } catch (MalformedPatternException e) { // TODO Auto-generated catch block e.printStackTrace(); } while(matcher.contains(pmi1,pattern1)) { MatchResult result1=matcher.getMatch(); lt.setTypeid(Integer.parseInt(result1.group(1))); lt.setOrder(result1.group(2)); lt.setOffset(Integer.parseInt(result1.group(3))); lt.setLength(Integer.parseInt(result1.group(4))); lt.setIfpic(Integer.parseInt(result1.group(5))); lt.setCirclePart(result1.group(6)); } //从数据库获取应该被替换成的最终文本 String orderway=""; String tiaojian=" where typeid="+lt.getTypeid(); String temptext=""; String circlePartold=lt.getCirclePart(); if(lt.getOrder().equals("tuijian")) { orderway=" order by tuijian DESC,addTime DESC "; } if(lt.getOrder().equals("date")) { orderway=" order by addTime DESC "; } if(lt.getIfpic()==1) tiaojian+="and ifpic=1 "; ResultSet r1=c.excutequery("select * from news"+tiaojian+orderway+" limit "+lt.getOffset()+","+lt.getLength()); try { while(r1.next()) { circlePartold=circlePartold.replaceAll("#pannycms:smallpic#", r1.getString("smallpic")); circlePartold=circlePartold.replaceAll("#pannycms:url#", r1.getString("filepath")); circlePartold=circlePartold.replaceAll("#pannycms:title#", r1.getString("title")); td.setTimestamp(r1.getInt("addTime")); String datetime=td.getTDate("Y-m-d H:i:s"); circlePartold=circlePartold.replaceAll("#pannycms:date#",datetime); circlePartold=circlePartold.replaceAll("#pannycms:click#",r1.getString("click")); temptext+=circlePartold+"\r\n"; circlePartold=lt.getCirclePart(); } } catch (SQLException e){ // TODO Auto-generated catch block e.printStackTrace(); } //执行替换,ss1替换成最终文本 //System.out.println(temptext); template=template.replace(ss1,temptext); } } //开始替换所有导航菜单 Pattern pattern2=null; try { pattern2=compiler.compile(regex3,Perl5Compiler.CASE_INSENSITIVE_MASK); } catch (MalformedPatternException e) { // TODO Auto-generated catch block e.printStackTrace(); } PatternMatcherInput pmi2=new PatternMatcherInput(template); while(matcher.contains(pmi2,pattern2)) { MatchResult result2=matcher.getMatch(); String ss3=result2.group(1); String menulink=""; int typeid=Integer.parseInt(result2.group(2)); ResultSet r3=c.excutequery("select menulink from newstype where typeid="+typeid); try { while(r3.next()) { menulink=r3.getString("menulink"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } template=template.replace(ss3,menulink); } //开始替换所有栏目地址链接 Pattern pattern3=null; try { pattern3=compiler.compile(regex4,Perl5Compiler.CASE_INSENSITIVE_MASK); } catch (MalformedPatternException e) { // TODO Auto-generated catch block e.printStackTrace(); } PatternMatcherInput pmi3=new PatternMatcherInput(template); while(matcher.contains(pmi3,pattern3)) { MatchResult result3=matcher.getMatch(); String ss4=result3.group(1); String path=""; int typeid=Integer.parseInt(result3.group(2)); ResultSet r4=c.excutequery("select path from newstype where typeid="+typeid); try { while(r4.next()) { path=r4.getString("path"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } template=template.replace(ss4,path); } //关闭链接 c.close(); return template; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class ChangeHtml extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String url = ""; String name = ""; ServletContext sc = getServletContext(); String htmName = request.getParameter("htmName");// 要生成的htm文件名 String jspUrl = request.getParameter("jspUrl");//访问的jsp路径 String htmUrl = request.getParameter("htmUrl");//存放生成htm文件的路径 // 则你访问这个servlet时加参数.如http://localhost/test/toHtml?file_name=index //url = "/" + file_name + ".jsp";// 你要生成的页面的文件名。 我的扩展名为jsf . name = sc.getRealPath(htmUrl)+"\\"+ htmName + ".htm"; //System.out.println(name); //name = ConfConstants.CONTEXT_PATH+"\\"+ file_name + ".htm";// 这是生成的html文件名,如index.htm.文件名字与源文件名相同。扩展名为htm //ConfConstants.CONTEXT_PATH为你的应用的上下文路径。 RequestDispatcher rd = sc.getRequestDispatcher(jspUrl); final ByteArrayOutputStream os = new ByteArrayOutputStream(); final ServletOutputStream stream = new ServletOutputStream() { public void write(byte[] data, int offset, int length) { os.write(data, offset, length); } public void write(int b) throws IOException { os.write(b); } }; final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os)); HttpServletResponse rep = new HttpServletResponseWrapper(response) { public ServletOutputStream getOutputStream() { return stream; } public PrintWriter getWriter() { return pw; } }; rd.include(request, rep); pw.flush(); FileOutputStream fos = new FileOutputStream(name); // 把jsp输出的内容写到xxx.htm os.writeTo(fos); fos.close(); System.out.println("页面已经成功生成"); //PrintWriter out = response.getWriter(); //out.print("

页面已经成功生成!single
http://www.agilejava.org/space/? 233

"); } } 最近自己刚刚搞了个静态页系统。  基本上都是用Freemarker生成的。  表的设计上,除了普通存放作者,发布时间的表(称之为原表)之外,还有有个专一存放静态页地址和路径的表,其中有上篇和下篇文章的URL(静态表)。  生成静态页容易,难点在生成以后更新上篇或下篇或者一些动态内容。这部分内容需要楼主多东东脑筋,自己写方案解决,其实慢慢来就可以了。。下边简单说下。 首先根据ID或者发布时间查找该类别下 上一遍文章,通过freemarker生成静态页后将当前文章地址插入上条记录中的“下一篇内容”,再提取出上一遍的URL等信息,存入当前信息的“上一篇”。。同时在原表中插入当前URL信息(搜索时可直接显示静态的URL地址)。 最后,更新上一遍文章中的“下一篇”为当前的信息。可以选择用ajax局部更新,或者Str.replaceAll()来重写页面。 至于列表页,也可以用freemarker来实现。。freemarker中有遍历数组的方法。 至于其他动态内容,可以用ajax实现,例如DWR,可以将动态内容首先放入资源文件,通过dwr调用(避免读取数据库)。通过TIMER(或其他实现)每隔一段时间重写一次要读取资源文件。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档