前辈们提提(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
[解决办法]
[解决办法]
同意5楼的观点:
首页尽量做成碎片方式,比如:分成 头 脚 ,栏目1列表,栏目2列表等。便于维护和更新,显示的时候使用ssi组件拼装在一起,门户往往这么做
数据库尽量设计得简单,尽量不要存储冗余字段,静态页面之间的链接是在生成静态页面的时候就生成的。
[解决办法]
如何处理分页显示?
[解决办法]
如果没有什么特殊要求的话,重写jsp中的out(JswWriter)对象是最简单快捷的实现方式
[解决办法]
1.怎么生成静态页面呢,如首页,列表怎么生成?内容可以通过做一个模块来生成,因为首页比较复杂,该怎么生成?
你学一下velocity,freemarker之类的模板技术,用它来做三个模板页面,一个是首页,一个是列表页,一个是内容页
2.生成静态网页之后数据库中的是怎么存的呢?要存些什么信息呢,或者静态页面之间是怎么联系起来的
数据库中不需要保存静态页面的信息
3.怎么更新呢,如果生成静态页面了之后,怎么更新列表和首页呢
你可以在后台管理中让用户手动点击按钮来生成静态页,或者用一个定时器来自动定时生成静态页,或者每次有内容更新时均调用静态页面生成
[解决办法]
mark
[解决办法]
mark
[解决办法]
读index.jsp的内容然后重新命名为index.html
java中有一个方法可以读取URL的内容。
[解决办法]
1 列表项可以,在增加项目时候分别生成相应的静态页面,
显示的主页面可以用jsp页面来包含各个不同学的列表表态页面。
别用ajax,否则会更慢。
[解决办法]
用freemarker吧 逻辑和你写jsp一模一样
分页也一模一样的 我们都在用 可以借鉴一下
给你个地址你看看
http://info.tsts168.com/tsts/q/in/desc/1.html
[解决办法]
学习了!!!
[解决办法]
学习..
[解决办法]
[解决办法]
另外 补充一点 像你这样的类型我一般不建议你生成HTML
[解决办法]
关注下
很多页面确实需要生成静态
[解决办法]
mark
[解决办法]
jf
[解决办法]
IIS静态配置方案
http://www.nuli365.com/ReadCode.aspx?id=383
[解决办法]
学习
[解决办法]
学习了
[解决办法]
学习...
[解决办法]
文章分页列表我是用Ajax,其他的全部生成HTML
[解决办法]
[解决办法]
我们是做企业应用开发的,没有这方面的经验,谈一下自己的想法。
首先做静态化是为了加速读取速度,是不能加速查询速度的,这一点
我认为必须明确,淡然了如果比较牛的话自己写Cache算法除外。
对于首页模块的列表,因为是用Ajax加载的,所以可以把显示数据
定期从数据库中查询出来,或者手动通过后台指定,然后写到xml或
其他文件格式里,这样首页模块中列表内容的缓存就做好了。
对于论坛的帖子这种,可以想CSDN一样用帖子记录的GUID做主键生成
静态HTML,当有人回帖的时候,除了向数据库中写记录以外,顺便
更新静态文件,这样内容的缓存就做好了。
对于如何做查询缓存不清楚,一点愚见希望对你有所帮助
[解决办法]
通过ajax 局部更新
[解决办法]
关注
[解决办法]
学习了~~~~~~
[解决办法]
学习了!
[解决办法]
帮顶,学习一下
[解决办法]
up
[解决办法]
学习
[解决办法]
记号
[解决办法]
cms内容管理系统就是干这个的
[解决办法]
freemarker + oscache
[解决办法]
路过 随口说的
------解决方案--------------------
freemarker 定义模板,生成静态的页面不就完了.
没向你说的,问的那么难吧.
真汗.....
[解决办法]
你看看http://pipi.cn已经到达了300万的在线用户,也都是这样做的啊.
[解决办法]
2.前台布局使用sitemsh布局框架构建表现层的结构
3.前台数据记录的展现使用displayTag框架实现数据记录的展现,分页,排序
[解决办法]
[解决办法]
几十万就慢,那得先看看你的数据库了.
如果热点很突出,可以做一下缓存.
[解决办法]
这个可以mark一下
[解决办法]
up
[解决办法]
mark..
[解决办法]
asp 的生成,部分代码:
dim objXmlHttp
set objXmlHttp = server.createobject("msxml2.xmlhttp")
objXmlHttp.open "GET",strUrl,false
objXmlHttp.send()
Dim binFileData
binFileData = objXmlHttp.responseBody
Dim objAdoStream
set objAdoStream = Server.CreateObject("ADODB.Stream")
objAdoStream.Type = 1
objAdoStream.Open()
objAdoStream.Write(binFileData)
objAdoStream.SaveToFile FilePath,2
objAdoStream.Close()
1、首页,可以写一个程序,用crontab每几分钟执行一回
2、列表用假静态。
3、文章保存是,自己生成html(如果中间部分想随时自己改,生成shtml)
[解决办法]
访问量比较大的网站,可以在用户前端加一个squid。
cache等
[解决办法]
可以尝试这2个方法:
1, 避免重复请求相同内容。例如用ajax只更新局部信息,用模板引擎velocity, freemark之类.
2, 缓存重复请求的信息,避免每次读取db。这个优化是绝对要得。
[解决办法]
Ajax只是客户友好体验,不代表速度快!
不需要Ajax的地方就没有必要使用的
[解决办法]
~~
[解决办法]
我在做站的时候也遇到过这样的问题,我是下载的freemarker,然后将从数据库中读到的数据在freemarker 上生成一个静态页面的摸版就OK了.楼主不要想的那么难哈...
[解决办法]
学习学习
[解决办法]
反对Ajax,ajax说白了就是客户端的jave,最终工作还要落在服务器端的处理上,这样的压力也很要命的.
支持绝对静态生成.
还是
1.怎么生成静态页面呢,如首页,列表怎么生成?内容可以通过做一个模块来生成,因为首页比较复杂,该怎么生成?
首页如变化大可以采用调用xml(比纯静态的慢),如果版式固定则按模版生成.第一种只需要每次写xml文件和数据库就可以了,另一种就是每条都要重写首页.内容页面用JAVA实现上下页之间关联,这样避免重复生成和条与条之间的衔接(我以前的一个安全站点就这么做的,如404则返回指定页静态实现),列表页面可以指定满N条生成(首页和内容翻页及关联能解决列表的不足)
2.生成静态网页之后数据库中的是怎么存的呢?要存些什么信息呢,或者静态页面之间是怎么联系起来的
基本上数据库给我就是备用的数据资料,除了优化外不做手脚
3.怎么更新呢,如果生成静态页面了之后,怎么更新列表和首页呢
在1里已说
[解决办法]
好好厉害啊
[解决办法]
学习一JAVA编程思想第二版本有一这课了
[解决办法]
这样写挺不好的。代码显不规范化
[解决办法]
完全虽然做了不少系统,我还没有遇到这个问题,期待楼主有个好的解决方案!新浪网数据也很多,但是也很快啊!
[解决办法]
完全虽然做了不少系统,我还没有遇到这个问题,期待楼主有个好的解决方案!新浪网数据也很多,但是也很快啊!
[解决办法]
up
[解决办法]
缓存...CDN
[解决办法]
学习~~~~
[解决办法]
ajax也不是适合任何地方的~~
[解决办法]
这个东西很难呀
[解决办法]
10万的数据都慢,那说明你的sql的执行效率太低了,或者是数据模型有问题。
[解决办法]
把url rewrite一下就可以了
[解决办法]
[解决办法]
up
[解决办法]
mark
[解决办法]
得隔断时间生成你的静态页面,把你的生成页面,用一些java函数来生成,这样
StringBuffer.append("<div>sdss</div>");
隔断时间生成一次。
[解决办法]
来学习
[解决办法]
用模板,比如velocity
最重要的是生成列表~~~~,如果数据少,可以每次全部生成,如果多的话,嘿嘿。最好以时间的方式来生成
[解决办法]
在关注中...
也很想明白这方面的知识.
[解决办法]
mark
[解决办法]
路过!
[解决办法]
... ... 做告的都里了。。。
[解决办法]
可以考虑cache,缓存之流。像csdn一样,3分钟更新下数据
[解决办法]
给你一个我做着玩的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<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下
[解决办法]
- Java code
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