精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Java>>JAVA编程>>Java与XML>>Java & XML手记(9)--在JSP中应用XML(二)

主题:Java & XML手记(9)--在JSP中应用XML(二)
发信人: zeus_h(i番茄)
整理人: zjxyz(2002-09-08 22:58:02), 站内信件
发信人: javalover (欲下未下风悠扬), 信区: Java
标  题: Java & XML手记(19)
发信站: 北大未名站 (2001年11月18日17:24:39 星期天) , 站内信件

19. 在JSP中应用XML(二)
(二)Tag Library和Tag的原理
    本小节将介绍Tag Library与Tag的工作原理,这个问题涉及到两大方面,第一个方面是JS
P程序的执行原理,第二个方面就是Tag的执行原理。
   我们首先介绍第一个方面---------JSP程序的运行原理,根据JSP1.2规范的描述,JSP程序
的运行可以分为这样的几个步骤。

◆Parsing
    在这一步,JSP引擎将检查JSP程序的源代码,看看是否有违反语法的地方,如果有,那么抛
出错误信息,不运行此JSP程序,如果一切正常,那么就把这个JSP程序翻译为XML文件的格式,也
就是把这个JSP程序按照XML文件的格式重新写一遍,我们在前面已经提到过,JSP程序有两种
书写方式,一种方式是普通的HTML标记加上JSP指令与Java脚本,第二种书写方式就是把JSP指
令替换为特定的XML标记,这些标记在一个DTD文件中给出了定义,所谓的Parsing过程就是把按
第一种方式书写的JSP程序翻译为以第二种方式书写的JSP程序,并加上一些debug信息,例如:
<%@ include file=”copyright.hmtl” %>
   将会被替换为:
<jsp:directive.include file=”copyright.html” />
   在这一过程中,JSP引擎还会处理include进来的文件,识别那些是由JSP指令转换过来的XM
L标记,那些是程序员自定义的标记。实际上,我们可以直接以第二种方式书写JSP程序,这样P
arsing 过程会被JSP引擎忽略掉,JSP程序的运行速度将有所加快的。

◆Validation
    这一步所作的工作就是验证JSP程序中所使用的自定义标记库,检查程序员是否正确使用
了该标记库的功能。JSP引擎会按照所使用的自定义标记库的出现顺序,逐个验证它们,查看每
一个自定义Tag是否有对应的TagExtraInfo 类(亦即下文的TEI类),如果有,那么就调用相应的
TagExtraInfo类的isValid()方法,检查程序员是否正确使用了该标记的属性与参数。

◆Translation
    在这一步中,JSP程序(XML格式的)被JSP引擎翻译为一个标准的Java类,该Java类一般继承
了HttpJspPage接口,覆盖了_jspService()方法。该类编译执行的结果就是我们所看到的JSP
程序的执行结果。请看下面的例子:

程序清单6.1(test.jsp):
<%
out.println("你好");
%>
    程序清单6.1经过JSP引擎翻译后所产生的Java类文件如下所示(程序清单6.2,有少量改动
,主要是代码缩进方面):

程序清单6.2:
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;
import org.apache.jasper.runtime.*;
import java.beans.*;
import org.apache.jasper.JasperException;

public class _0002ftest_0002ejsptest_jsp_1 extends HttpJspBase 
{
     static
         {
     }
     public _0002ftest_0002ejsptest_jsp_1( )
         {
     }

     private static boolean _jspx_inited = false;
     public final void _jspx_init() throws JasperException
         {
     }

public void _jspService(HttpServletRequest request, HttpServletResponse  respons
e)
         throws IOException, ServletException
{
        JspFactory _jspxFactory = null;
         PageContext pageContext = null;
         HttpSession session = null;
         ServletContext application = null;
         ServletConfig config = null;
         JspWriter out = null;
         Object page = this;
         String  _value = null;
         try
         {

             if (_jspx_inited == false)
                 {
                 _jspx_init();
                 _jspx_inited = true;
             }
             _jspxFactory = JspFactory.getDefaultFactory();
             response.setContentType("text/html;charset=8859_1");
             pageContext = _jspxFactory.getPageContext(this, request, response,
"", true, 8192, true);

             application = pageContext.getServletContext();
            config = pageContext.getServletConfig();
             session = pageContext.getSession();
             out = pageContext.getOut();

//begin [file="E:\\temp\\Down\\Tomcat3.2\\webapps\\ROOT\\test.jsp";
//from=(0,2);to=(2,0)]
                out.println("脛茫潞脙");
             // end
         }
catch (Exception ex)
{
             if (out.getBufferSize() != 0)
                 out.clearBuffer();
             pageContext.handlePageException(ex);
 }
finally
{
             out.flush();
             _jspxFactory.releasePageContext(pageContext);
         }
     }
}

注意:
    程序清单6.1/6.2所使用的JSP服务器为Tomcat 3.2,操作系统平台为Win Me,JDK版本为1
.3。

    根据程序清单6.2,我们应该获得这样的信息,该Java类继承自HttpJspPage接口,HttpJsp
Page接口又继承于JspPage接口,JspPage接口继承于Servlet接口,Servlet接口继承于Generi
cServlet类,可见,关于JSP程序被编译为一个Servlet类文件的说法还是有一定的道理的。S
ervlet程序几乎都继承了HttpServelt类,而HttpServlet类正是继承于GenericServlet类,所
以HttpJspPage接口和HttpServlet还是有点血缘关系的。在程序清单6.2中,最重要的方法是
_jspService()方法,该方法实现了JSP程序(程序清单6.1中的JSP程序)的所有功能,把”你好
”输出到客户端。

◆Execution
    这一步就是编译上面一步所产生的Java文件,产生class文件,并调用Java虚拟机执行它,
结果首先存放在缓冲区中,程序执行完毕,再一并输出到客户端。


20. 在JSP中应用XML(三)
Tag Library和Tag的原理-2
有人可能会问JSP程序的执行流程与Tag的工作原理又有何关系呢?我的回答是:有很大的关系
,请接着往下看,我们介绍这个问题的第二个方面-------Tag的工作原理。
要说Tag的工作原理,首先必须提到Tag/Tag Library的编写方法。Tag/Tag Library的编写方
法如下:

◆首先确立编写的目标
我们首先需要明确都需要实现那些目标,需要封装什么功能,Tag的名字是什么,初步设计Tag的
使用方法,Tag是否需要参数,这个Tag都需要那些属性,需要用到那个Java API,开发平台是什
么,这些问题我们都需要考虑得十分清楚。而且这些问题在考虑清楚以前不要轻易编写程序。

◆编写TLD文件
所谓的TLD文件,指的是Tag Library Descriptor Files,中文意义为标记库描述符文件。这是
一个XML格式的文件,它描述了Tag Library的详细信息,它的具体作用有以下几个方面。
1.指定此Tag Library的版本号。
2.指定Tag Library所遵守的JSP规范的版本号,至少是1.1。
3.指定此Tag Library的名字,例如Application。
4.指定此Tag Library的URI,普通资源定位符。
6.指定此Tag Library的验证类(validator class)。
6.指定此Tag Library的事件监听类(listener)。
6.一些注释信息。
对于特定的Tag,TLD文件给出了下面的信息。
1.指定了Tag的名字。
2.指定了Tag Hander,即真正实现了该Tag功能的Java类。
3.指定了TEI类,利用该类,可以获取Tag的附加信息,也就是获取Tag的某些属性值。
4.指定了Tag标记体内的数据类型。亦即<Tag>标记与</Tag>标记之间内容的数据类型。
6.一些注释信息。
6.指定了Tag的属性信息。

◆编写Tag Handler
当编写好TLD文件以后,我们就可以针对特定的Tag编写特定的Tag Handler了,真正实现Tag的
功能,当然了,Tag Handler的编写有一套规则,不是随便一个Java类都可以作为Tag Handler的
,我们在下文还要详细讨论这个问题。

◆打包Tag Library
我们为每一个Tag都编写好Tag Handler以后,就可以把所有的类文件与TLD文件打包到一个ja
r文件中。然后把它分发部署到JSP服务器上去,这需要对服务器的配置做一点小小的改动。

◆测试Tag Library
在这一步中,我们需要编写一个JSP程序,使用该Tag Library的Tag,看看是否实现了原来设计
的功能。请看下面的程序清单6.3,这是一个Tomcat 3.2服务器所自带的例子,有少量改动。

程序清单6.3(foo.jsp):
<html>
<body>
<%@ taglib uri="http://java.apache.org/tomcat/examples-taglib" prefix="eg" %>
Radio stations that rock:

    <eg:foo att1="98.5" att2="92.3" att3="107.7">
  • <%= member %>

  • </eg:foo>

<eg:log>
Did you see me on the stderr window?
</eg:log>
<eg:log toBrowser="true">
Did you see me on the browser window as well?
</eg:log>
</body>
</html>
在程序清单6.3中,首先使用taglib操作指令导入一个Tag Library-------simple,指定了该T
ag Library的URI地址与标识符(prefix=eg),在下面的代码段中,则分别验证了foo标记与log
标记的使用,foo标记与log标记都是属于simple Tag Library的标记。
到此为止,一个Tag Library就算开发成功了,我们除了可以自己使用这个Tag Library,也可
以把它上载到网络中,供别人使用。




----
象我这一种男人,学不懂怎快乐!就算简简单单幸福的角落,也未寻获。<br>
就算我对你再好,亦会比一张纸更薄,除非一天,我可给你快乐!

        

[关闭][返回]