Tapestry 3.0 输出功能的原理分析

来源:互联网 发布:中国地壳运动观测网络 编辑:程序博客网 时间:2024/05/17 04:26

   

     为了给客户浏览器输出html,首先,要把服务器端已经render好的html保存起来,按

字节操作的,本来可以直接创建个 OutputStream , 但是 tapestry自己写了一个,当然

是继承于OutputStream ,名字叫ResponseOutputStream,它在里面做了一些改动,比

若write()方法里加入了一个状态可以控制要不要写入。这重写OutputStream,当然是个

办法,如果不这样做,为了达到同样的目的,我觉的是不是可以这样,建立个

OutputStream,再把它放到 FilterOutputstream里面,做状态控制?当然这个新方法看

起来会更加的烦。回到tapestry的设计思路上来,建好了一个名字叫

ResponseOutputStream的OutputStream,但是,在上一层,也就是httpServlet 层中,

已经给我们建立好了一个OutputStream,因为tapestry是建立在servlet的基础上的,所

以只好把这个ResponseOutputStream当做是servlet那个OutputStream的副本。我对

servlet那个OutputStream没有什么研究,只好假设,servlet先是把处理过的html(暂叫它

为html文件)写到JVM中的缓冲区中,比若这样:

    ①

  OutputStream out = new OutputStream();

  out.wirte(" <html>");
 
  out.write("'很多html的tag'");

  out.write("</html>");
 
  out.close();

   好了,把html暂时写到jvm中的一块缓冲区中去了,这个缓冲区的引用是out,或者按

c/c++的叫法,这块缓冲区的指针是out。现在html文件已经在服务器端JVM 的一块缓冲

区保存完毕,现在的任务就是把它送到客户端去。

   我认为,本质上是用了java.net包Socket的Tcp/IP编程来实现输送功能,呵呵,但是

还是来看Servlet的对socket封装后的输送吧。

    Servlet用了FilterOutputstream中的PrintStream作为对socket的输出封装,反正我是

这么认为的。PrintStream是字符流的, 所以要把刚才的字节流先转化为字符流先,可

以看出J2EE在网络上应该是以字符为单位进行传递的吧?

  

  InputStreamReader in = new InputStreamReader(out);

  转化成字符流了,就应该把它送到客户端去了。

 

  PrintWriter pw = new  PrintWriter(in);

  in.close();
  
  pw.close();

假如,不先把html文件保存在服务器端,而是直接送出去的的话,①②③程序改写如下:
 
   OutputStream out = new OutputStream();
 
   InputStreamReader in = new InputStreamReader(out);

   PrintWriter pw = new  PrintWriter(in);

   pw.wirte(" <html>");
 
   pw.write("'很多html的tag'");

   pw.write("</html>");

   out.close();

   in.close();

   pw.close();


   tapestry 3.0 是怎么做的?我看了下源程序应该是这样的:

 

  RequestContext requestcontext = 由ApplicationContext创建出来;

  RequestCycle  requestcycle = 由Engine创建出来
 
  IPage page =  requestcycle.getPage();

  
 
  ResponseOutputStream  output =

                                new   ResponseOutputStream(requestcontext.getResponse());
 
  

 
   IMarkupWriter iMarkupWriter = page.getResponseWriter(output);

  

   requestcycle.renderPage(iMarkupWriter);

 

比较一下:其实就是①,以Tapestry的方式获取Servlet的outputStream;

                  其实就是③,这样看来IMarkupWriter好象就是FilterOutputStream的一种

                     似的,等同于Servlet的PrintWriter;
         
                    但是怎么看呢? 我想应该这样来吧,猜的先:
 
           public  Interface IMarkupWriter{

                    public void write();

                   public void close();
            
     }
 

            public class RequestCycle{

                     public void rendPage( IMarkupWriter iw){

                     iw.write();
        
                     iw.close();
 
      }

    这样的话,rendPage方法就真的把tapestry输出给封装起来了。

    看了一下源代码,IMarkupWriter和我设计的差不多,反正就这个意思。至于

rendPage方法 ,最后调用的是renderComponent(),这个方法的实现,在自己设计自己

的Component时,经常是我们自己写代码实现的,看起来和我的设计思想也差不多。

      看起来,这样子分析Tapestry 3.0 输出功能的原理,很有可能是对的了。