礼问一个jsp动态页面生成静态页面完整方案!!!! 100分散完再散啦.

时间:2022-11-12 23:41:54
大致看了一下前面的帖子。最基本的原理是先建立模板,然后填模板。但很多时候页面根据不同的参数来显示不同的内容。这时候用模板就感觉不灵活。所以需要一个不需要建立模板的方案.

另外,有几处模糊的地方就是,生成的静态文件怎样发送到客户端呢。 例如:
  我请求的页面是:index.jsp  那么服务器接收请求,生成了静态的index.html后,怎样发送到客户端,让客户端看到的是静态页面index.html,而不是index.jsp呢。

还有,用户请求的是jsp文件,那么服务器也是运行这个文件后然后再生成html文件的吧。如此来说,速度会快的原理是什么?不是很明白。望高手指点其中的奥妙.

49 个解决方案

#1


1.利用servlet的mapping

2.java生成html文件是用servlet的一个线程,这个线程所属的进程是常驻内存的,所以很快

#2


先做个静太的模板页,然后用下面这个类去读取它
ReadTemplates.java 

package ball.news; 
import java.io.*; 
import java.util.*; 

public class ReadTemplates 


private String temp = null; 
private Object a = new Object(); 

public ReadTemplates() 



public String getTlpContent(String s) 


if(temp == null) 
synchronized(a) 

if(temp == null) 
try 

System.out.println("----------------------------"); 
temp = a(s); 
//System.out.println("test the temp"+temp); 

catch(Exception e) 

System.out.println("get tlpconente error"+e.getMessage()); 


return temp; 


private synchronized String a(String s) 


String s1 = null; 
try 

FileInputStream fileinputstream = new FileInputStream(s); 
int i = fileinputstream.available(); 
byte abyte0[] = new byte[i]; 
fileinputstream.read(abyte0); 
fileinputstream.close(); 
s1 = new String(abyte0); 

catch(IOException e) 

System.out.println("ioexception error"+e.getMessage()); 

return s1; 




再把读取到的模板中的你想要替换掉的比如新闻标题,内容等的东西替换掉,用下面这个类
 
package ball.news;
import java.io.*;
import news.ReadTemplates;
public class  ReplaceAll
{
 private static Object a = new Object();
 public ReplaceAll()
 { 
 }

 public String replace(String content,String flag,String temp)
 {
  String str = null;
  
        try
        {
         //System.out.println("before-----"+content);
         String s1 = content;
            str = s1.replaceAll(flag,temp);  
           // System.out.println("replace after-----"+str);
        }
        catch(Exception e)
        {
         System.out.println("replace all error:"+e.getMessage());
        }
        return str;
        
    }
    private static void a(String s)
    {
        File file = new File(s);
        if(!file.exists())
            file.mkdirs();
    }
}

然后生成HTML
WriteHtml.java 

package ball.news; 

import java.io.*; 

public class WriteHtml 


public WriteHtml() 



public static void save(String s, String s1, String s2) 


try 

a(s1); 
FileOutputStream fileoutputstream = new FileOutputStream(s1 + s2); 
byte abyte0[] = s.getBytes(); 
fileoutputstream.write(abyte0); 
fileoutputstream.close(); 

catch(IOException e) 

System.out.println("write html error"+e.getMessage()); 



private static void a(String s) 

try 

File file = new File(s); 
if(!file.exists()) 
file.mkdirs(); 

catch (Exception e) 

System.out.println("mkdirs error!"+e.getMessage()); 



#3


我只知道使用模板哈!其他的我还不知道哈!不过帮你顶一下哈!

#4


顶起来

#5


面向搜索引擎的内容管理系统(CMS)设计——利用Squid反相代理缓存实现网站内容静态发布
http://blog.csdn.net/feng_sundy/archive/2005/07/26/435531.aspx

#6


mark

#7


to shanshuiboy: 基本上你没有怎么看我的问题就来答,因为我是不想用模板来做,不过还是谢谢你的回答.

to feng_sundy: 你的这个答复是解决怎样被搜索引擎收录而重定向地址的方案,这个有一定的价值,不过不是解决我提出的访问速度问题。

继续等待高手出现...

#8


抛砖引玉:下面这个方法是一个被一些网友证实的例子,不过还是不太明白几点:
这个代码中说将jsp页面作为参数传输,那么一个jsp页面里带的参数如何处理?例子说index.jsp, 如果是访问index.jsp?par=1$par=2 这样的怎么处理?
 第二个,这个方法的访问是 http://localhost/toHtml?file_name=index,而我想要的是 比如客户端访问的是 index.jsp,但返回给客户的实际上是 index.html。

请教高手了!!!

JSP生成静态页面- -
                                       


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 toHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
    
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("file_name");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name+".jsp";//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.

        name="/home/resin/resin-2.1.6/doc/"+file_name+".htm";//这是生成的html文件名,如index.htm.
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red>首页已经成功生成!Andrew</font></p>");
    }
}

#9


这个问题有点深度哦
小弟来学习了

#10


访问×××.jsp后,生成×××.html后,要把html发送到客户端,可以对response处理,让客户端重新定位到该××××.html地址。

但是想说的是,没有这样用的。
如果你要把整个系统做成静态的,静态页面是在添加数据的时候生成的。
静态页面的访问地址是固定的。例如http://***.com/news/2006/04/15/****.html
不需要根据.jsp,然后生成.html,然后再重新定位到.html。

如果你每次访问jsp,还要生成html,这样没有任何优化作用。
生成html是将以发布的内容都生成html,以后访问的时候直接访问该html,以达到大用户访问的需求。

#11


学习中……
不过好像要将现在动态改成静态,需要改动的地方太多了~~~~

没有更好的解决方法吗?

#12


是的,你增加一篇新闻,不是说别人请求就生成一次HTML文件,而是你增加的时候就生成了的。这样才能发挥HTML速度的优势。

#13


to yonghar(ohno):
你说的就是我想的,我就是在想如果这样生成html再返回客户端的话。效率在哪里会提高呢。
不过如果用后台发布来做的话。又涉及信息的及时性的问题.

#14


按照前面我贴的代码从后台生成html静态页面,页面生成了,但新的问题出来了,乱码!!!!!!!!
这个是我的页面头:
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
以前jsp文件的时候还需要这样:
<%@ page language="java" 
    contentType="text/html;charset=iso8859_1" %>

现在完全乱码。劳驾高手看看代码:



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 toHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
    
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("file_name");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name+".jsp";//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.

        name="/home/resin/resin-2.1.6/doc/"+file_name+".htm";//这是生成的html文件名,如index.htm.
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red>首页已经成功生成!Andrew</font></p>");
    }
}

#15


建议你去搜下摸版引型

#16


sourceURL 是jsp的路径  destFilePath 是html页面的名称
public static boolean copyFromURL(String sourceURL, String destFilePath) {
    System.out.println("sourceURL = " + sourceURL);
    RandomAccessFile destFile = null;
    InputStream inStream = null;
    try {
      destFile = new RandomAccessFile(destFilePath, "rw");
      URL url = new java.net.URL(sourceURL);
      URLConnection conn = url.openConnection();
      inStream = conn.getInputStream();
      byte[] buffer = new byte[512];

      int lineRead = 0;
      while ( (lineRead = inStream.read(buffer, 0, 512)) != -1) { //EOF
        destFile.write(buffer, 0, lineRead);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    finally {
      try {
        if (destFile != null) {
          destFile.close();
        }
      }
      catch (Exception e) {
      }

      try {
        if (inStream != null) {
          inStream.close();
        }
      }
      catch (Exception e) {
      }
    }
    return true;
  }

#17


好贴啊,我一直梦寐以求的需要解决项目的方法啊。
多谢各位大侠,我以前一直认为前台页面处理还是php和asp等实现访问速度比较快,一直想找个办法来实现jsp转换成html的方法,实现效果都不理想。
现在看到这么多的帖子,很是激动。

#18


如果从后台确实是可能会导致不同步。

否则如果每修改一次记录或增加一条记录就重新生一个相应的html文件,这种方法可以保证同步,不过如果网站复杂度,关联很多的话就要很多代码要改写了,有没有在目前动态网站上通过较少的改动可以实现静态生成的方法,值得讨论?

#19


已经搞定。采用的方案是后台发布接合前台实时生成。
后台发布就不用说了。在jsp页面同时可以添加代码,先检测时候有对应的静态页面,如果有则转向,没有则立刻生成,然后转向,这个检测的频度是每天一次(其中可以用临时文件处理)。这样的话,即时后台有些页面没有实现或者不是很好实现静态页面与实时数据的影响问题,也可以生成静态页面。
   这样做法的好处是保证每天(频度可以自己定义)能生成最新数据的静态页面。不好是比纯静态页面略慢,且每天第一个访问页面的人比较倒霉,会比访问jsp还慢(添加了生成过程).

非常谢谢 yonghar(ohno)-帮助我理清了思路
谢谢 zuguanqun(小群) - 提供了一个可行的解决乱码的代码。

谢谢大家热烈的回复.

#20


大家可以继续讨论。稍晚点再结贴.

#21


只要大家对大家有帮助就好啊
我的MSN

#22


我的MSN lieying2@sina.com 
有兴趣大家一起交流

#23


哦,查看的时候开始是到一个jsp文件,然后转向到静态的?
我是直接直接生成静态文件,然后访问时用那个你转向的页面内嵌静态文件,表面上看上去是.jsp的,然后把评论放在另外的页面里留一个连接,点评论连接的时候查转向页面里的新闻id显示对应的。。
我想问yonghar(ohno),完全直接上静态页面不经过转向的jsp怎么评论?

#24


不错,看看jsp也可以实现现php ob_get_content那样的功能了.呵呵,谢谢大家

#25


先FOLLOW,随后慢慢看。

#26


修改一下:

package com.kevin.html;

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 ToHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
     response.setContentType("text/html; charset=GBK");
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("filename");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name;//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.
        String filename = file_name.substring(0,file_name.lastIndexOf("."));

        name= sc.getRealPath("/") + "doc/"+filename+".htm";//这是生成的html文件名,如index.htm.
        System.out.println(name);
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red><a href='doc/"+filename+".htm'>" + name + "</a>已经成功生成!</font></p>");
    }
}



有个问题请教:
        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);
            }
        };
这是一个内部类吗? 有什么作用??

#27


试了一下,去掉上面这个类也是可以的。

#28


第一,不是内部类,而是方法调用的内部方法
第二,根据不同的输入参数选择不同的方法载入运用。
第一个是输出数据流的,第二个个人以为是生成或者显示参数用的。

#29


up

#30


好人好贴好分

#31


踩个印先

#32


appman(沙砾),可以说说你具体的做法吗?贴部分代码开学习学习吧:)

#33


方法调用的内部方法??呵呵,第一次听说有这样的方法。那个应该是内隐类来的(anonymous  inner class)

#34


mark

#35


该回复被版主删除

#36


这里归纳了一些内隐类方面的知识:-)  http://www.ideagrace.com

#37


inner class也要声明是 class好不好..
你仔细看代码?仅仅是一个method。。
一个method里面包含的method。。。

#38


好帖,学了很多我不懂的东西

#39


内隐类是不用声明class的,呵呵

#40


正在学生成HTML

#41


接分!

#42


jf

#43



内隐类是不用声明class的,呵呵
----去看java core ii或者THU出的java大学教材..
照你的说法方法内部调用其他方法都被你说成inner class了.

很简单
方法内部调用别的方法这种写法很奇怪?你咋写java的,helloworld还要调用一个系统输出呢.

#44


呵呵,,方法内部当然可以调用别的方法了.我并没有说觉得奇怪啊.只是在这里并不是这个情况,看过tij里面的内部类那篇就明白了.

#45


好贴,定!个路英雄都出来啦。

#46


mark

#47


太多了没看,JSP/ASP/PHP等页面在客户端显示本来就是HTML页面!

#48


已经没人响应了,结贴了!

#49


高手呀,
刚学JSP;
学习中···

#1


1.利用servlet的mapping

2.java生成html文件是用servlet的一个线程,这个线程所属的进程是常驻内存的,所以很快

#2


先做个静太的模板页,然后用下面这个类去读取它
ReadTemplates.java 

package ball.news; 
import java.io.*; 
import java.util.*; 

public class ReadTemplates 


private String temp = null; 
private Object a = new Object(); 

public ReadTemplates() 



public String getTlpContent(String s) 


if(temp == null) 
synchronized(a) 

if(temp == null) 
try 

System.out.println("----------------------------"); 
temp = a(s); 
//System.out.println("test the temp"+temp); 

catch(Exception e) 

System.out.println("get tlpconente error"+e.getMessage()); 


return temp; 


private synchronized String a(String s) 


String s1 = null; 
try 

FileInputStream fileinputstream = new FileInputStream(s); 
int i = fileinputstream.available(); 
byte abyte0[] = new byte[i]; 
fileinputstream.read(abyte0); 
fileinputstream.close(); 
s1 = new String(abyte0); 

catch(IOException e) 

System.out.println("ioexception error"+e.getMessage()); 

return s1; 




再把读取到的模板中的你想要替换掉的比如新闻标题,内容等的东西替换掉,用下面这个类
 
package ball.news;
import java.io.*;
import news.ReadTemplates;
public class  ReplaceAll
{
 private static Object a = new Object();
 public ReplaceAll()
 { 
 }

 public String replace(String content,String flag,String temp)
 {
  String str = null;
  
        try
        {
         //System.out.println("before-----"+content);
         String s1 = content;
            str = s1.replaceAll(flag,temp);  
           // System.out.println("replace after-----"+str);
        }
        catch(Exception e)
        {
         System.out.println("replace all error:"+e.getMessage());
        }
        return str;
        
    }
    private static void a(String s)
    {
        File file = new File(s);
        if(!file.exists())
            file.mkdirs();
    }
}

然后生成HTML
WriteHtml.java 

package ball.news; 

import java.io.*; 

public class WriteHtml 


public WriteHtml() 



public static void save(String s, String s1, String s2) 


try 

a(s1); 
FileOutputStream fileoutputstream = new FileOutputStream(s1 + s2); 
byte abyte0[] = s.getBytes(); 
fileoutputstream.write(abyte0); 
fileoutputstream.close(); 

catch(IOException e) 

System.out.println("write html error"+e.getMessage()); 



private static void a(String s) 

try 

File file = new File(s); 
if(!file.exists()) 
file.mkdirs(); 

catch (Exception e) 

System.out.println("mkdirs error!"+e.getMessage()); 



#3


我只知道使用模板哈!其他的我还不知道哈!不过帮你顶一下哈!

#4


顶起来

#5


面向搜索引擎的内容管理系统(CMS)设计——利用Squid反相代理缓存实现网站内容静态发布
http://blog.csdn.net/feng_sundy/archive/2005/07/26/435531.aspx

#6


mark

#7


to shanshuiboy: 基本上你没有怎么看我的问题就来答,因为我是不想用模板来做,不过还是谢谢你的回答.

to feng_sundy: 你的这个答复是解决怎样被搜索引擎收录而重定向地址的方案,这个有一定的价值,不过不是解决我提出的访问速度问题。

继续等待高手出现...

#8


抛砖引玉:下面这个方法是一个被一些网友证实的例子,不过还是不太明白几点:
这个代码中说将jsp页面作为参数传输,那么一个jsp页面里带的参数如何处理?例子说index.jsp, 如果是访问index.jsp?par=1$par=2 这样的怎么处理?
 第二个,这个方法的访问是 http://localhost/toHtml?file_name=index,而我想要的是 比如客户端访问的是 index.jsp,但返回给客户的实际上是 index.html。

请教高手了!!!

JSP生成静态页面- -
                                       


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 toHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
    
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("file_name");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name+".jsp";//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.

        name="/home/resin/resin-2.1.6/doc/"+file_name+".htm";//这是生成的html文件名,如index.htm.
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red>首页已经成功生成!Andrew</font></p>");
    }
}

#9


这个问题有点深度哦
小弟来学习了

#10


访问×××.jsp后,生成×××.html后,要把html发送到客户端,可以对response处理,让客户端重新定位到该××××.html地址。

但是想说的是,没有这样用的。
如果你要把整个系统做成静态的,静态页面是在添加数据的时候生成的。
静态页面的访问地址是固定的。例如http://***.com/news/2006/04/15/****.html
不需要根据.jsp,然后生成.html,然后再重新定位到.html。

如果你每次访问jsp,还要生成html,这样没有任何优化作用。
生成html是将以发布的内容都生成html,以后访问的时候直接访问该html,以达到大用户访问的需求。

#11


学习中……
不过好像要将现在动态改成静态,需要改动的地方太多了~~~~

没有更好的解决方法吗?

#12


是的,你增加一篇新闻,不是说别人请求就生成一次HTML文件,而是你增加的时候就生成了的。这样才能发挥HTML速度的优势。

#13


to yonghar(ohno):
你说的就是我想的,我就是在想如果这样生成html再返回客户端的话。效率在哪里会提高呢。
不过如果用后台发布来做的话。又涉及信息的及时性的问题.

#14


按照前面我贴的代码从后台生成html静态页面,页面生成了,但新的问题出来了,乱码!!!!!!!!
这个是我的页面头:
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
以前jsp文件的时候还需要这样:
<%@ page language="java" 
    contentType="text/html;charset=iso8859_1" %>

现在完全乱码。劳驾高手看看代码:



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 toHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
    
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("file_name");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name+".jsp";//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.

        name="/home/resin/resin-2.1.6/doc/"+file_name+".htm";//这是生成的html文件名,如index.htm.
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red>首页已经成功生成!Andrew</font></p>");
    }
}

#15


建议你去搜下摸版引型

#16


sourceURL 是jsp的路径  destFilePath 是html页面的名称
public static boolean copyFromURL(String sourceURL, String destFilePath) {
    System.out.println("sourceURL = " + sourceURL);
    RandomAccessFile destFile = null;
    InputStream inStream = null;
    try {
      destFile = new RandomAccessFile(destFilePath, "rw");
      URL url = new java.net.URL(sourceURL);
      URLConnection conn = url.openConnection();
      inStream = conn.getInputStream();
      byte[] buffer = new byte[512];

      int lineRead = 0;
      while ( (lineRead = inStream.read(buffer, 0, 512)) != -1) { //EOF
        destFile.write(buffer, 0, lineRead);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    finally {
      try {
        if (destFile != null) {
          destFile.close();
        }
      }
      catch (Exception e) {
      }

      try {
        if (inStream != null) {
          inStream.close();
        }
      }
      catch (Exception e) {
      }
    }
    return true;
  }

#17


好贴啊,我一直梦寐以求的需要解决项目的方法啊。
多谢各位大侠,我以前一直认为前台页面处理还是php和asp等实现访问速度比较快,一直想找个办法来实现jsp转换成html的方法,实现效果都不理想。
现在看到这么多的帖子,很是激动。

#18


如果从后台确实是可能会导致不同步。

否则如果每修改一次记录或增加一条记录就重新生一个相应的html文件,这种方法可以保证同步,不过如果网站复杂度,关联很多的话就要很多代码要改写了,有没有在目前动态网站上通过较少的改动可以实现静态生成的方法,值得讨论?

#19


已经搞定。采用的方案是后台发布接合前台实时生成。
后台发布就不用说了。在jsp页面同时可以添加代码,先检测时候有对应的静态页面,如果有则转向,没有则立刻生成,然后转向,这个检测的频度是每天一次(其中可以用临时文件处理)。这样的话,即时后台有些页面没有实现或者不是很好实现静态页面与实时数据的影响问题,也可以生成静态页面。
   这样做法的好处是保证每天(频度可以自己定义)能生成最新数据的静态页面。不好是比纯静态页面略慢,且每天第一个访问页面的人比较倒霉,会比访问jsp还慢(添加了生成过程).

非常谢谢 yonghar(ohno)-帮助我理清了思路
谢谢 zuguanqun(小群) - 提供了一个可行的解决乱码的代码。

谢谢大家热烈的回复.

#20


大家可以继续讨论。稍晚点再结贴.

#21


只要大家对大家有帮助就好啊
我的MSN

#22


我的MSN lieying2@sina.com 
有兴趣大家一起交流

#23


哦,查看的时候开始是到一个jsp文件,然后转向到静态的?
我是直接直接生成静态文件,然后访问时用那个你转向的页面内嵌静态文件,表面上看上去是.jsp的,然后把评论放在另外的页面里留一个连接,点评论连接的时候查转向页面里的新闻id显示对应的。。
我想问yonghar(ohno),完全直接上静态页面不经过转向的jsp怎么评论?

#24


不错,看看jsp也可以实现现php ob_get_content那样的功能了.呵呵,谢谢大家

#25


先FOLLOW,随后慢慢看。

#26


修改一下:

package com.kevin.html;

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 ToHtml extends HttpServlet
{

    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    String url="";
    String name="";
     response.setContentType("text/html; charset=GBK");
        ServletContext sc = getServletContext();
        
        String file_name=request.getParameter("filename");//你要访问的jsp文件,如index.jsp
  //则你访问这个servlet时加参数.如http://localhost/toHtml?file_name=index

        url = "/"+file_name;//这是你要生成HTML的jsp文件,如
                                   //http://localhost/index.jsp的执行结果.
        String filename = file_name.substring(0,file_name.lastIndexOf("."));

        name= sc.getRealPath("/") + "doc/"+filename+".htm";//这是生成的html文件名,如index.htm.
        System.out.println(name);
                
        RequestDispatcher rd = sc.getRequestDispatcher(url);
        
        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();
        PrintWriter out=response.getWriter();
        out.print("<p align=center><font size=3 color=red><a href='doc/"+filename+".htm'>" + name + "</a>已经成功生成!</font></p>");
    }
}



有个问题请教:
        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);
            }
        };
这是一个内部类吗? 有什么作用??

#27


试了一下,去掉上面这个类也是可以的。

#28


第一,不是内部类,而是方法调用的内部方法
第二,根据不同的输入参数选择不同的方法载入运用。
第一个是输出数据流的,第二个个人以为是生成或者显示参数用的。

#29


up

#30


好人好贴好分

#31


踩个印先

#32


appman(沙砾),可以说说你具体的做法吗?贴部分代码开学习学习吧:)

#33


方法调用的内部方法??呵呵,第一次听说有这样的方法。那个应该是内隐类来的(anonymous  inner class)

#34


mark

#35


该回复被版主删除

#36


这里归纳了一些内隐类方面的知识:-)  http://www.ideagrace.com

#37


inner class也要声明是 class好不好..
你仔细看代码?仅仅是一个method。。
一个method里面包含的method。。。

#38


好帖,学了很多我不懂的东西

#39


内隐类是不用声明class的,呵呵

#40


正在学生成HTML

#41


接分!

#42


jf

#43



内隐类是不用声明class的,呵呵
----去看java core ii或者THU出的java大学教材..
照你的说法方法内部调用其他方法都被你说成inner class了.

很简单
方法内部调用别的方法这种写法很奇怪?你咋写java的,helloworld还要调用一个系统输出呢.

#44


呵呵,,方法内部当然可以调用别的方法了.我并没有说觉得奇怪啊.只是在这里并不是这个情况,看过tij里面的内部类那篇就明白了.

#45


好贴,定!个路英雄都出来啦。

#46


mark

#47


太多了没看,JSP/ASP/PHP等页面在客户端显示本来就是HTML页面!

#48


已经没人响应了,结贴了!

#49


高手呀,
刚学JSP;
学习中···