中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > Web开发 > JSP > Servlets
漫步j2ee之jsp技术(2)
作者:未知 时间:2005-07-24 21:21 出处:JR 责编:chinaitpower
              摘要:漫步j2ee之jsp技术(2)
(承接 漫步j2ee之jsp技术(1))

首先说明一下,这是我写的关于j2ee技术介绍的第五篇文章,这篇是专门讨论jsp技术,适合有一定的jsp基础的人员参考总结用。

Resin服务器的输出如下:
Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001
http listening to *:8080
srun listening to 127.0.0.1:6802
BulidConnection()方法被调用
会话级别的数据库连接已经建立!!!
由此可知,当DBBean1.jsp文件中定义DBCon对象的生命周期为session时,就触发了HttpSessionBindingEvent事件,并调用了valueBound方法,建立了“会话级别的数据库联机”。
然后,我们再在DBBean2.jsp等多个页面中跳转,Resin服务器的输出仍然如上所示,这就表明了,同一会话中的各个页面均使用了同一个数据库联机,所以才没有建立新的联机。
当关闭服务器的时候,输出数据如下:
Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001
http listening to *:8080
srun listening to 127.0.0.1:6802
BulidConnection()方法被调用
会话级别的数据库连接已经建立!!!
closing server
会话级别的数据库连接已经关闭!!!
此时,会话结束,触发了HttpSessionBindingEvent事件,并调用了valueUnbound方法,关闭了先前建立的会“话级别的数据库联机”。
4.    Bean的保存与读取
到目前为止,我们所使用的Bean对象均能于建立该对象的页面中使用,而无法将执行的结果保存下来供下次页面执行使用。现在,我们就来讨论一下Bean的保存的问题。
若要某个Bean对象保存进文件,就必须使该Bean可串行化,即该Bean必须实现java.io.Serializable接口。
另外,如果要把Bean对象保存进文件,或是从文件中读取Bean对象,需要用到四个特别的java.io包中的对象,它们是FileOutputStream、ObjectOutputStream、FileInputStream、ObjectInputStream,其中的前两个使用来保存Bean对象的,后两个则是用来读取Bean对象的。具体的使用方法,我们还是通过例子来说明吧!!!
²    Bean对象的保存与读取
我们将要建立如下几个文件,它们的用途及说明如下表:
文件名称    说明    用途
SaveBean.java    定义要保存进文件的Bean对象,此对象将实现Serializable接口。    此Bean中将保存姓名、性别、年龄、生日、爱好这五个个人信息。
BeanSaver.java    定义将Bean对象保存进文件,或是从文件中读取Bean对象的BeanSaver对象。    用来保存或是读取Bean对象。
SaveBean.jsp    建立SaveBean对象,并设定相应的个人信息,然后,把此对象写入文件。    建立SaveBean对象,并利用BeanSaver对象把SaveBean对象写入文件SB.ser。
LoadBean.jsp    利用BeanSaver对象,从文件中取得SaveBean对象。    从文件SB.ser中取得SaveBean对象,然后将其内容,即个人信息显示在页面上。
两个Bean的源文件如下:
SaveBean.java
  1. /*
  2.  * 文件名:SaveBean.java
  3.  *
  4.  * 类名:SaveBean
  5.  *
  6.  * 所属包:j2ee.jsp
  7.  *
  8.  * 导入包:import java.io.*;
  9.  *
  10.  * 作者:杨??
  11.  *
  12.  * 创建时间:2003.12.10
  13.  *
  14.  * 用途描述:用来设定个人的相关信息,并且可以保存到文件的JavaBean。
  15.  * 
  16.  * 版本号:1.0
  17.  *
  18.  */
  19. package j2ee.jsp;
  20. import java.io.*;
  21. //定义SaveBean类别实现Serializable接口
  22. public class SaveBean implements Serializable
  23. {
  24.     //内部属性
  25.     private String name = "";
  26.        private String sex = "";
  27.        private int age = 25;
  28.        private String birth = "";
  29.        private String love = "";
  30.     
  31.        //以下为设定Bean属性的方法
  32.        public void setName(String name)
  33.        {
  34.            this.name = name;
  35.        }
  36.        public void setSex(String sex)
  37.        {
  38.            this.sex = sex;
  39.        }
  40.        public void setAge(int age)
  41.        {
  42.            this.age = age;
  43.        }
  44.        public void setBirth(String birth)
  45.        {
  46.            this.birth = birth;
  47.        }
  48.        public void setLove(String love)
  49.        {
  50.            this.love = love;
  51.        }
  52.        //以下为获取Bean属性的方法
  53.        public String getName()
  54.        {
  55.            return this.name;
  56.        }
  57.        public String getSex()
  58.        {
  59.            return this.sex;
  60.        }
  61.        public int getAge()
  62.        {
  63.            return this.age;
  64.        }
  65.        public String getBirth()
  66.        {
  67.            return this.birth;
  68.        }
  69.        public String getLove()
  70.        {
  71.            return this.love;
  72.        }
  73. }
  74. BeanSaver.java
  75. /*
  76.  * 文件名:BeanSaver.java
  77.  *
  78.  * 类名:BeanSaver
  79.  *
  80.  * 所属包:j2ee.jsp
  81.  *
  82.  * 导入包:import java.io.*;
  83.  *
  84.  * 作者:杨??
  85.  *
  86.  * 创建时间:2003.12.10
  87.  *
  88.  * 用途描述:将Bean对象保存进文件,或是从文件中读取Bean对象的JavaBean对象。
  89.  * 
  90.  * 版本号:1.0
  91.  *
  92.  */
  93. package j2ee.jsp;
  94. import java.io.*;
  95. public class BeanSaver
  96. {
  97.       /**
  98.        * 方法名:save
  99.        * 级别:public
  100.        * @param     Ojbect     Bean对象 
  101.        * @param     String     Bean对象要存放到的文件及其路径 
  102.        * @return    boolean    告知操作是否成功
  103.        * @throws    (无)
  104.        * 作用:将Bean对象写入文件中,以便日后使用
  105.        */
  106.     public boolean save(Object obj, String filename)
  107.     {
  108.         boolean result = true;
  109.     
  110.         try
  111.         {
  112.             FileOutputStream fos = 
  113.                  new FileOutputStream(filename);
  114.             //建立FileOutputStream对象
  115.             ObjectOutputStream oos = 
  116.                     new ObjectOutputStream(fos);
  117.             //建立ObjectOutputStream对象
  118.             oos.writeObject(obj);
  119.             //将对象写入文档
  120.             
  121.             oos.close(); //关闭对象
  122.         }
  123.         catch(Exception ex)    
  124.         {    
  125.             result = false//设定回传写入失败
  126.             System.out.println(ex.toString());
  127.         }
  128.         
  129.         return result; //回传对象是否成功写入文档
  130.     }
  131.       /**
  132.        * 方法名:load
  133.        * 级别:public
  134.        * @param     String     存放Bean对象的文件及其路径
  135.        * @return    Object     从文件中取得的Bean对象
  136.        * @throws    (无)
  137.        * 作用:取得保存在.ser文件中的Bean对象
  138.        */
  139.     public Object load(String filename)
  140.     {
  141.         Object obj = null;
  142.         try
  143.         {
  144.             FileInputStream fis = 
  145.                  new FileInputStream(filename);
  146.             //建立FileInputStream对象
  147.             ObjectInputStream ois = 
  148.                     new ObjectInputStream(fis);
  149.             //建立ObjectInputStream对象
  150.             obj = ois.readObject();
  151.             //从文档读取对象
  152.             
  153.             ois.close(); //关闭对象            
  154.         }
  155.         catch(Exception ex)    
  156.         {    
  157.             System.out.println(ex.toString());
  158.         }
  159.         
  160.         return obj; //回传从文档读取出的对象
  161.     }    
  162. }

编译上面的两个源文件,产生j2ee.jsp.SaveBean.class与j2ee.jsp.BeanSaver.class。
两个jsp页面的程序代码如下:
SaveBean.jsp
  1. <%@ page contentType="text/html; charset=GB2312" %>
  2. <HTML>
  3. <HEAD>
  4. <TITLE>Bean对象的保存与取得</TITLE>
  5. </HEAD>
  6. <BODY>
  7. <CENTER>
  8. <FONT SIZE = 5 COLOR = blue>Bean对象的保存</FONT>
  9. </CENTER>
  10. <HR>
  11. <jsp:useBean id="info" scope="page"  
  12.     class="j2ee.jsp.SaveBean"/>
  13. <%
  14. //调用Bean对象的方法, 设定属性
  15. info.setName("最后的决定");
  16. info.setSex("男");
  17. info.setAge(22);
  18. info.setBirth("1981-9-10");
  19. info.setLove("流行音乐,武侠剧,唱歌,互联网,漂亮mm");
  20. %>
  21. <jsp:useBean id="saver" scope="page"  
  22.     class="j2ee.jsp.BeanSaver"/>
  23. <%
  24. //保存对象
  25. saver.save(info,"D:\\java\\SB.ser");
  26. %>
  27. <H2>
  28. SaveBean对象已经保存完毕
  29. </H2>
  30. </BODY>
  31. </HTML>
  32. LoadBean.jsp
  33. <%@ page contentType="text/html; charset=GB2312"
  34.     import="j2ee.jsp.*"%>
  35. <HTML>
  36. <HEAD>
  37. <TITLE>Bean对象的保存与取得</TITLE>
  38. </HEAD>
  39. <BODY>
  40. <CENTER>
  41. <FONT SIZE = 5 COLOR = blue>Bean对象的取得</FONT>
  42. </CENTER>
  43. <HR>
  44. <P></P>
  45. <jsp:useBean id="saver" scope="page"  
  46.     class="BeanSaver"/>
  47. <jsp:useBean id="info" scope="page"  
  48.     class="SaveBean"/>
  49. <%
  50. //将对象设定至pageContext对象中
  51. pageContext.setAttribute("info", saver.load("d:\\java\\SB.ser"));
  52. //若欲已调用Bean对象方法的方式运用Bean时, 需使用此叙述
  53. info = (SaveBean) pageContext.getAttribute("info");
  54. %>
  55. 个人资料<br>
  56. <Font color = red>姓名:</Font>
  57. <Font color = blue>
  58. <%= info.getName() %></Font><BR>
  59. <Font color = red>性别:</Font>
  60. <Font color = blue>
  61. <%= info.getSex() %></Font><BR>
  62. <Font color = red>年龄:</Font>
  63. <Font color = blue>
  64. <%= info.getAge() %></Font><BR>
  65. <Font color = red>生日:</Font>
  66. <Font color = blue>
  67. <%= info.getBirth() %></Font><BR>
  68. <Font color = red>爱好:</Font>
  69. <Font color = blue>
  70. <%= info.getLove() %></Font><BR>
  71. </BODY>
  72. </HTML>

首先在运行SaveBean.jsp,结果如下:
 
然后运行LoadBean.jsp,显示如下:
 
至此,恭喜你已经学会了JavaBeans所有最核心的应用了,jsp强大的功用也已经展现在了你的眼前,快去构建威力无穷的Web应用吧,祝你一路顺风:) 。

六.    JSP中的文件操作


自从有了数据库系统以后,文件的操作似乎变得不再那么重要了,很多大型的应用系统也往往愿意把数据的存取工作交给数据库而不是文件。就笔者自身的体会是,数据库的确在很多时候可以替代文件,但在某些特定的应用上使用文件可以得到更佳的应用效果和方便的操作特性,而且在操作少量数据的存取时,文件不但方便保存携带,更不像数据库那样运行时需要消耗大量的服务器资源。因此,笔者认为,文件的操作仍然是一个重点。
要在JSP中操作文件,大体上需要用到java.io.*包中的数个类及其相应的方法,很多时候实现同一功能都有数种不同的方法。在此,笔者不想在各个类的基本定义格式及其相应方法的说明上多费笔墨,而是直接把一个集合了众多文件操作功能的Bean呈现在各位读者面前。使用此Bean,可以进行绝大多数的文件操作,至于其中具体到某个类、某个方法的操作原理及其细节,请各位参看相关资料。
下表列出了CtrlFile类的所有公开方法及其说明:
方法名    用途说明
createNewFile    建立一个新的文件
deleteFile    删除文件
createNewDir    建立一个新的目录
deleteDir    删除目录
fileLength    测量文件的长度
isFile    判断是不是文件
isDir    判断是不是目录
readLine    读取文件的第一行
readAll    读取整个文件的内容
writeLine    把数据写入文件
writeAppend    把数据追加入文件
  1. /*
  2.  * 文件名:CtrlFile.java
  3.  *
  4.  * 类名:CtrlFile
  5.  *
  6.  * 所属包:j2ee.jsp
  7.  *
  8.  * 导入包:import java.io.*;
  9.  *
  10.  * 作者:杨??
  11.  *
  12.  * 创建时间:2003.12.10
  13.  *
  14.  * 用途描述:对目录、文件进行读、写、新建、删除等操作。
  15.  * 
  16.  * 版本号:1.0
  17.  *
  18.  */
  19. package j2ee.jsp;
  20. import java.io.*;
  21. //注意:各个函数中要到的参数path均为实际路径.
  22. public class CtrlFile
  23. {
  24.     
  25.     /**
  26.      * 方法名:FileName
  27.      * 级别:private
  28.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  29.      * @return    String     文件名
  30.      * @throws    (无)
  31.      * 作用:从文件的实际路径中取出文件名
  32.      */
  33.      private String FileName(String path)
  34.             {
  35.                  int pos = path.lastIndexOf('\\');
  36.                  String FileName = path.substring(pos+1);
  37.                  return(FileName);                 
  38.             }       
  39.     /**
  40.      * 方法名:PathName
  41.      * 级别:private
  42.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  43.      * @return    String     路径
  44.      * @throws    (无)
  45.      * 作用:从文件的实际路径中取出路径
  46.      */
  47.      private String PathName(String path)    
  48.             {
  49.                  int pos = path.lastIndexOf('\\');
  50.                  String PathName = path.substring(0,pos);
  51.                  return(PathName);    
  52.             }
  53.             
  54.     /**
  55.      * 方法名:createNewFile
  56.      * 级别:public
  57.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  58.      * @param     boolean    是否覆盖
  59.      * @return    (无)
  60.      * @throws    Exception  如果发生错误
  61.      * 作用:建立一个新的文件
  62.      */
  63.      public void createNewFile(String path,boolean rebuild) throws Exception           
  64.            {    
  65.                 String FileName = new String(FileName(path));
  66.                 String PathName = new String(PathName(path));
  67.                 File f = new File(PathName,FileName);
  68.                 if(rebuild==true)
  69.                     {
  70.                         if(f.exists()==true)
  71.                             {
  72.                                 f.delete();
  73.                             }    
  74.                         f.createNewFile();      
  75.                     }   
  76.                 else
  77.                     {
  78.                         if(f.exists()==false)
  79.                             {
  80.                                 f.createNewFile();    
  81.                             }    
  82.                     }
  83.            
  84.            }
  85.     /**
  86.      * 方法名:deleteFile
  87.      * 级别:public
  88.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  89.      * @return    (无)
  90.      * @throws    Exception  如果发生错误
  91.      * 作用:删除文件
  92.      */
  93.      public void deleteFile(String path)  throws Exception
  94.            {
  95.                    String FileName = new String(FileName(path));
  96.                    String PathName = new String(PathName(path));
  97.                 File f = new File(PathName,FileName);
  98.                 f.delete();    
  99.            }
  100.            
  101.     /**
  102.      * 方法名:createNewDir
  103.      * 级别:public
  104.      * @param     String     目录的实际路径
  105.      * @param     boolean    是否覆盖
  106.      * @return    (无)
  107.      * @throws    Exception  如果发生错误
  108.      * 作用:建立一个新的目录
  109.      */
  110.      public void createNewDir(String path,boolean rebuild) throws Exception
  111.            {
  112.                 File d = new File(path);
  113.                 if(rebuild==true)
  114.                     {
  115.                         if(d.exists()==true)
  116.                             {
  117.                                 d.delete();    
  118.                             }    
  119.                         d.mkdir();    
  120.                     }    
  121.                 else
  122.                     {
  123.                         if(d.exists()==false)
  124.                             {
  125.                                 d.mkdir();    
  126.                             }    
  127.                     }    
  128.            }    
  129.            
  130.     /**
  131.      * 方法名:deleteDir
  132.      * 级别:public
  133.      * @param     String     目录的实际路径
  134.      * @return    (无)
  135.      * @throws    Exception  如果发生错误
  136.      * 作用:删除目录
  137.      */
  138.      public void deleteDir(String path) throws Exception
  139.            {
  140.                 File d = new File(path);
  141.                 d.delete();    
  142.            }       
  143.            
  144.     /**
  145.      * 方法名:fileLength
  146.      * 级别:public
  147.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  148.      * @return    long       文件的长度
  149.      * @throws    Exception  如果发生错误
  150.      * 作用:测量文件的长度
  151.      */
  152.      public long fileLength(String path) throws Exception
  153.            {
  154.                String FileName = new String(FileName(path));
  155.                String PathName = new String(PathName(path));
  156.                 File f = new File(PathName,FileName);
  157.                 long fileLength = f.length();
  158.                 return(fileLength);    
  159.            }      
  160.            
  161.     /**
  162.      * 方法名:isFile
  163.      * 级别:public
  164.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  165.      * @return    boolean    是否文件
  166.      * @throws    Exception  如果发生错误
  167.      * 作用:用来判断是不是文件
  168.      */
  169.      public boolean isFile(String path) throws Exception
  170.            {
  171.                String FileName = new String(FileName(path));
  172.                String PathName = new String(PathName(path));
  173.                 File f = new File(PathName,FileName);
  174.                 boolean isFile = f.isFile();
  175.                 return(isFile);                    
  176.            }       
  177.            
  178.     /**
  179.      * 方法名:isDir
  180.      * 级别:public
  181.      * @param     String     目录的实际路径
  182.      * @return    boolean    是否目录
  183.      * @throws    Exception  如果发生错误
  184.      * 作用:用来判断是不是目录
  185.      */
  186.      public boolean isDir(String path) throws Exception
  187.            {
  188.                 File d = new File(path);
  189.                 boolean isDir = d.isDirectory();
  190.                 return(isDir);    
  191.            }      
  192. /*-------------------------以上是针对文件的操作-------------------------*/
  193.            
  194. /*-------------------------以下是针对文件的读写-------------------------*/
  195.     /**
  196.      * 方法名:readLine
  197.      * 级别:public
  198.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  199.      * @return    String     文件中第一行的内容
  200.      * @throws    Exception  如果发生错误
  201.      * 作用:用来读取文件的第一行
  202.      */
  203.      public String readLine(String path) throws Exception
  204.            {
  205.                 FileReader fr = new FileReader(path);
  206.                 BufferedReader br = new BufferedReader(fr);
  207.                 String Line = br.readLine();
  208.                 return(Line);    
  209.            } 
  210.            
  211.     /**
  212.      * 方法名:readAll
  213.      * 级别:public
  214.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  215.      * @return    String     文件中的所有内容
  216.      * @throws    Exception  如果发生错误
  217.      * 作用:用来读取整个文件的内容
  218.      */
  219.      public String readAll(String path) throws Exception           
  220.            {
  221.                 FileReader fr = new FileReader(path);
  222.                 BufferedReader br = new BufferedReader(fr);
  223.                 String txt = new String();
  224.                 String Line = new String();
  225.                 Line = br.readLine();
  226.                 while(Line!=null)
  227.                      {
  228.                          txt = txt + Line;
  229.                          Line = br.readLine();    
  230.                      }    
  231.                 br.close();
  232.                 fr.close();
  233.                 return(txt);     
  234.            }
  235.     /**
  236.      * 方法名:writeLine
  237.      * 级别:public
  238.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  239.      * @param     String     要写入文件中的内容
  240.      * @return    (无)
  241.      * @throws    Exception  如果发生错误
  242.      * 作用:用来把数据写入文件
  243.      */                      
  244.      public void writeLine(String path,String content) throws Exception    
  245.            {
  246.                 FileWriter fw = new FileWriter(path);
  247.                 fw.write(content);
  248.                 fw.close();    
  249.            }
  250.     /**
  251.      * 方法名:writeAppend
  252.      * 级别:public
  253.      * @param     String     文件的实际路径 , 即:路径 + 文件名 
  254.      * @param     String     要写入文件中的内容
  255.      * @return    (无)
  256.      * @throws    Exception  如果发生错误
  257.      * 作用:用来把数据追加入文件
  258.      */   
  259.      public void writeAppend(String path,String content) throws Exception    
  260.            {
  261.                 FileWriter fw = new FileWriter(path,true);
  262.                 PrintWriter pw = new PrintWriter(fw);
  263.                 pw.print(content + "\n");
  264.                 pw.close();
  265.                 fw.close();    
  266.            }
  267. }

七.    JSP运行原理剖析


谈到JSP的运行原理,就不得不谈到Servlet了。虽然按照Sun的观点,将来是要用JSP替代Servlet的,但JSP是在Servlet的基础上发展起来的,要深刻理解JSP的运行原理,就一定需要Servlet的相关知识。在阅读本节前,笔者假设你已经至少对Servlet有了基本的概念理解。OK,不再多说废话了,Let’s go!!
Servlet技术的出现时间很早,是当时为了Java的服务器端应用而开发的。大家都知道Applet是应用小程序,Servlet就是服务器端小程序了。但在Microsoft公司的ASP技术出现后,使用Servlet进行响应输出时一行行的输出语句就显得非常笨拙,对于复杂布局或者显示页面更是如此。JSP就是为了满足这种需求在Servlet技术之上开发的。可见,JSP和Servlet之间有着内在的血缘关系,在学习JSP时,如果能够抓住这种联系,就能更深刻地理解JSP的运行机理,达到事半功倍的效果。 
JSP页面的请求响应过程如下图:
 
下面笔者举例说明:
HelloWorld.jsp代码清单如下:
  1. <%@ page contentType="text/html; charset=GB2312"%>
  2. <HTML>
  3. <HEAD>
  4. <TITLE>Hello World</TITLE>
  5. </HEAD>
  6. <BODY>
  7. <%="Hello World!!!!!!"%>
  8. </BODY>
  9. </HTML>

这个文件存放在D:\java\resin1.2.2\webapps中,通过浏览器请求执行HelloWorld.jsp:
http://127.0.0.1:8080/helloworld.jsp。
服务器resin接到这个请求后,调出jsp引擎,首先将HelloWorld.jsp解析成Servlet存入D:\java\resin1.2.2\work\_jsp目录,文件名是_helloworld__jsp.java,此Servlet的源代码如下:
  1. /*
  2.  * JSP generated by Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001
  3.  */
  4. package _jsp;
  5. import java.io.*;
  6. import javax.servlet.*;
  7. import javax.servlet.jsp.*;
  8. import javax.servlet.jsp.tagext.*;
  9. import javax.servlet.http.*;
  10. public class _helloworld__jsp extends com.caucho.jsp.JavaPage{
  11.   
  12.   public void
  13.   _jspService(javax.servlet.http.HttpServletRequest request,
  14.               javax.servlet.http.HttpServletResponse response)
  15.     throws java.io.IOException, javax.servlet.ServletException
  16.   {
  17.     com.caucho.jsp.QPageContext pageContext = (com.caucho.jsp.QPageContext)
  18.       com.caucho.jsp.QJspFactory.create().getPageContext(
  19.       this, request, response, nulltrue, 8192, true);
  20.     javax.servlet.jsp.JspWriter out = (javax.servlet.jsp.JspWriter
  21.       pageContext.getOut();
  22.     javax.servlet.ServletConfig config = getServletConfig();
  23.     javax.servlet.Servlet page = this;
  24.     javax.servlet.http.HttpSession session = pageContext.getSession();
  25.     javax.servlet.ServletContext application = pageContext.getServletContext();
  26.     response.setContentType("text/html; charset=GB2312");
  27.     try {
  28.       pageContext.write(_jsp_string0, 0, _jsp_string0.length);
  29.       out.print(("Hello World!!!!!!"));
  30.       pageContext.write(_jsp_string1, 0, _jsp_string1.length);
  31.     } catch (java.lang.Throwable e) {
  32.       pageContext.handlePageException(e);
  33.     } finally {
  34.       JspFactory.getDefaultFactory().releasePageContext(pageContext);
  35.     }
  36.   }
  37.   private com.caucho.java.LineMap _caucho_line_map;
  38.   private java.util.ArrayList _caucho_depends = new java.util.ArrayList();
  39.   public boolean _caucho_isModified()
  40.   {
  41.     if (com.caucho.util.CauchoSystem.getVersionId() != -1355223632)
  42.       return true;
  43.     for (int i = _caucho_depends.size() - 1; i >= 0; i--) {
  44.       com.caucho.vfs.Depend depend;
  45.       depend = (com.caucho.vfs.Depend) _caucho_depends.get(i);
  46.       if (depend.isModified())
  47.         return true;
  48.     }
  49.     return false;
  50.   }
  51.   public long _caucho_lastModified()
  52.   {
  53.     return 0;
  54.   }
  55.   public com.caucho.java.LineMap _caucho_getLineMap()
  56.   {
  57.     return _caucho_line_map;
  58.   }
  59.   public void init(com.caucho.java.LineMap lineMap,
  60.                    com.caucho.vfs.Path appDir)
  61.     throws javax.servlet.ServletException
  62.   {
  63.     com.caucho.vfs.Path resinHome = com.caucho.util.CauchoSystem.getResinHome();
  64.     com.caucho.vfs.MergePath mergePath = new com.caucho.vfs.MergePath();
  65.     mergePath.addMergePath(appDir);
  66.     mergePath.addMergePath(resinHome);
  67.     mergePath.addClassPath(getClass().getClassLoader());
  68.     _caucho_line_map = new com.caucho.java.LineMap
  69.       ("_helloworld__jsp.java""/helloworld.jsp");
  70.     _caucho_line_map.add(1, 1);
  71.     _caucho_line_map.add(1, 27);
  72.     _caucho_line_map.add(7, 28);
  73.     com.caucho.vfs.Depend depend;
  74.     depend = new com.caucho.vfs.Depend(appDir.lookup("helloworld.jsp"), 
  75.       1071120876000L, 155L);
  76.     _caucho_depends.add(depend);
  77.   }
  78.   private static byte []_jsp_string1;
  79.   private static byte []_jsp_string0;
  80.   static {
  81.     try {
  82.       _jsp_string1 = "\r\n</BODY>\r\n</HTML>".getBytes("GB2312");
  83.       _jsp_string0 = "\r\n<HTML>\r\n<HEAD>\r\n<TITLE>Hello World</TITLE>\r\n</HEAD>\r\n<BODY>\r\n".
  84.        getBytes("GB2312");
  85.     } catch (java.io.UnsupportedEncodingException e) {
  86.       e.printStackTrace();
  87.     }
  88.   }
  89. }

从上面可以看出,HelloWorld.jsp在运行时首先解析成一个Java类_helloworld__jsp.java,该类继承于com.caucho.jsp.JavaPage基类,此基类实现了HttpServlet接口。可见,JSP在运行前首先将编译为一个Servlet,这就是理解JSP技术的关键。 
我们还知道JSP页面中内置了几个对象,如pageContext、application、config、page、session、out等,你可能会奇怪,为什么在JSP中的代码片断中可以直接使用这些内置对象。观察_jspService()方法,实际上这几个内置对象就是在这里定义的。在对JSP文件中的代码片断进行解析之前,先对这几个内置对象进行初始化。 
原来jsp文件中的“<%="Hello World!!!!!!"%>”被翻译成了“out.print(("Hello World!!!!!!"));”。
jsp引擎将HelloWorld.jsp解析成_helloworld__jsp.java后,再将_helloworld__jsp.java编译成_helloworld__jsp.class,接着执行_helloworld__jsp.class,这时才通过out内置对象将HelloWorld.jsp页面内容送至客户端的浏览器。
最后,_helloworld__jsp.class就存入了服务器电脑的内存里,往后再执行请求页面HelloWorld.jsp时,就直接执行存于服务器电脑内存里面的_helloworld__jsp.class了。
本篇“JSP技术”到此结束,一路走来,笔者详述了jsp的整个框架结构以及开发中最核心的技术应用,最后还从全新的角度对jsp的运行原理进行了阐述。现在,你是否感觉自己已经是个jsp的高手了呢?

--------------------====全文完===-----------------

author:杨坤 address:华中科技大学 qq:281174319
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有