前辈们提提(java)生成静态页方案
我现在在做一个访问量比较大的网站,现在遇到一问题,随着数据表记录越来越大,查询变得很慢,像大型网站都是生成静态页面的,我有些疑问:
1.怎么生成静态页面呢,如首页,列表怎么生成?内容可以通过做一个模块来生成,因为首页比较复杂,该怎么生成?
2.生成静态网页之后数据库中的是怎么存的呢?要存些什么信息呢,或者静态页面之间是怎么联系起来的
3.怎么更新呢,如果生成静态页面了之后,怎么更新列表和首页呢
[解决办法]
通过ajax 局部更新
[解决办法]
你应该从提高数据库性能方面考虑! 常查询的表要建好索引. 当然你也要确认你的代码质量没问题.
[解决办法]
1.怎么生成静态页面呢,如首页,列表怎么生成?内容可以通过做一个模块来生成,因为首页比较复杂,该怎么生成?
一般用freemarker生成静态页面.
静态页面的生成是有一定设计规律的:
首页是尽量使用静态文件,现在有些公司都使用“所见即所得”的编辑方式,就是使用网上的网页编辑器(Ewebeditor,FCKeditor等)对首页等进行编辑,之后通过文件流写入固定文件中。
列表一般都是动态提取的,也有生成静态的。例如电影网站有发布功能,就是将一定时间中要发布的电影列表生成静态文件,这也是为了缓解数据库压力。
记录(一条新闻,一条影讯)的具体内容一般是使用静态页面。因为涉及的图片和文字比较多,从数据库提取会慢。
具体方式:
(1)没有发布,在添加时就让用户看到。在添加记录时,相关的图片,说明文字等都要填写全,在保存时将内容生成静态文件,并记录文件的路径,在用户浏览时,链接到静态文件。
(2)有发布模块管理。添加人只负责填写全信息,由管理员负责发布内容,生成文件,用户只能看到发布的文件,新录入的文件是看不到的。
2.生成静态网页之后数据库中的是怎么存的呢?要存些什么信息呢,或者静态页面之间是怎么联系起来的
数据库存的是静态页面的路径,在用户浏览时,看到的是基本信息,链接的是详细信息。
3.怎么更新呢,如果生成静态页面了之后,怎么更新列表和首页呢
在修改时重新生成静态页面。或在重新发布时生成静态页面。
[解决办法]
给你个思路,你们的新闻页面应该是个固定模板,你把这个固定模板一个些静态的和动态的东西都放到stringBuffer类里面,然后用io输出流可以生成一个完整的 html页面,动态的从数据库读取就可以了,新生成的html页面用当前日期格式化一下(唯一),这样每篇文章不就对应一个静态页了吗?
给你一点代码:StirngBuffer bf = new StringBuff();
bf.append("<%@ page contentType='text/html; charset=gb2312'%>");
bf.append("<html>");
bf.append("<head>")
bf.append("<title>'"+articleInfo.getWebName+"'</title>");
bf.append("</head>");
bf.append("<body>");
bf.append("</body>");
bf.append("</html>");
然后用io接收bf生成静态页就可以了,还闲不够的话也可以把生成的静态页的名字,文章id之类的动态生成一个js,只要页面加载这个js生成相应的表格就可以了,这样 不管读哪的文章只是读取了一次js而已,服务器唯一的压力就是生成文章的时候,重新刷新了一下js而已,希望这个思路对你有帮助
呵呵..
[解决办法]
up
[解决办法]
[解决办法]
用freemarker吧 逻辑和你写jsp一模一样
分页也一模一样的 我们都在用 可以借鉴一下
给你个地址你看看
http://info.tsts168.com/tsts/q/in/desc/1.html
[解决办法]
学习了!!!
[解决办法]
学习..
[解决办法]
[解决办法]
up
[解决办法]
缓存...CDN
[解决办法]
学习~~~~
[解决办法]
ajax也不是适合任何地方的~~
[解决办法]
这个东西很难呀
[解决办法]
10万的数据都慢,那说明你的sql的执行效率太低了,或者是数据模型有问题。
[解决办法]
把url rewrite一下就可以了
[解决办法]
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<String> bigtext=new Vector<String>(); 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; }}
[解决办法]
一段将网页静态化的java代码
[解决办法]
我认为,提高数据库的查询速度,首先得对数据库的表关系改成级联操作,通过主外键联系,其次,在页面上采用真分页显示.再次,就是尽量将页面模块化,分成多块,
然后在页面包含到相应位置,对动态查询部分采取级联查询,或建个索引!
[解决办法]
很简单,有一种早已失传的技术,就是页面静态化技术,你可以使用模板引擎技术,velocity就是一种模板引擎,你可以用他实现你的页面静态化。
[解决办法]
mark下
[解决办法]
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("<p align=center><font size=3 color=red>页面已经成功生成!single<br>http://www.agilejava.org/space/? 233</font></p>"); } }
[解决办法]
最近自己刚刚搞了个静态页系统。
基本上都是用Freemarker生成的。
表的设计上,除了普通存放作者,发布时间的表(称之为原表)之外,还有有个专一存放静态页地址和路径的表,其中有上篇和下篇文章的URL(静态表)。
生成静态页容易,难点在生成以后更新上篇或下篇或者一些动态内容。这部分内容需要楼主多东东脑筋,自己写方案解决,其实慢慢来就可以了。。下边简单说下。
首先根据ID或者发布时间查找该类别下 上一遍文章,通过freemarker生成静态页后将当前文章地址插入上条记录中的“下一篇内容”,再提取出上一遍的URL等信息,存入当前信息的“上一篇”。。同时在原表中插入当前URL信息(搜索时可直接显示静态的URL地址)。 最后,更新上一遍文章中的“下一篇”为当前的信息。可以选择用ajax局部更新,或者Str.replaceAll()来重写页面。
至于列表页,也可以用freemarker来实现。。freemarker中有遍历数组的方法。
至于其他动态内容,可以用ajax实现,例如DWR,可以将动态内容首先放入资源文件,通过dwr调用(避免读取数据库)。通过TIMER(或其他实现)每隔一段时间重写一次要读取资源文件。
大致就这样,可能叙述的不是太清楚,效率也不是很高。。只是给楼主个思路。
[解决办法]
up
[解决办法]
mark