Archive for the ‘Flash Remoting’ Category

NetBeans 5.5配置Remoting & Java开发环境

用自己最爱的IDE配置一下Remoting & Java开发环境。下面就是步骤了:
 1.首先建立一个项目我这里就叫JF(这个名字关系到以后Remoting调用远程网关的名字):
(1)File > New Project (Ctrl + Shift + N) 
(2) 然后在choose project对话框中选择web 点击Next
(3)  在New Project Application 里面填写Project Name 这里我填的JF,然后NEXT(由于NetBeans里面自带Tomcat5.5版本所以不必将自己的文件一定要放到手动配置的TOMCAT里面)
(4)在Frameworks里面将两个框架都选中,这样方便以后开发的拓展

2.下面我们将要开始对开发环境进行配置,NETBEANS对WEB.XML和LIB的配置都是简介的,步骤如下:
(1)在左侧的项目视窗里面打开JF的文件树,右击Libraries,在显示的列表中选择ADD JAR/Folder(这就是打包以后的lib文件下的目录)
(2)在弹出的文件选择对话框中选择flashgateway.jar文件,该文件在你安装的FLASH REMOTING MX FOR J2EE包中的WAR文件中,可以用RAR或者命令解压文件,大家也可以看的出来,把它放到TOMCAT中,重新启动也会建立项目文件夹

3.修改WEB.XML文件,对项目进行配置
(1)双击WEB.XML文件,在右侧的编辑框里面,点击Servlet按钮,该项是用来添加Servlet的,点击Add Servlet Element 按钮
(2)在弹出的对话框里配置Servlet,在添加好以后在其下面的Initialization Parameters里面添加初始参数,
Servlet 和Initialization Parameters参数如下表:
    <servlet>
        <servlet-name>FlashGatewayServlet</servlet-name>
        <display-name>Flash Remoting MX Servlet</display-name>
        <description>Servlet-based plugin to Flash Remoting</description>
        <servlet-class>flashgateway.controller.GatewayServlet</servlet-class>
        <init-param>
            <param-name>LOG_LEVEL</param-name>
            <param-value>Error</param-value>
            <description>Controls the level of information logged.</description>
        </init-param>
        <init-param>
            <param-name>DISABLE_JAVA_ADAPTERS</param-name>
            <param-value>false</param-value>
            <description>When set to true, this setting disables the Java Service Adapters in the gateway.</description>
        </init-param>
        <load-on-startup>1</load-on-startup>//该行需要手动添加
    </servlet>

    <servlet-mapping>
        <servlet-name>FlashGatewayServlet</servlet-name>
        <url-pattern>/gateway</url-pattern>
    </servlet-mapping>
4.测试环境配置是否成功,选中index.jsp文件后右击 选择RUN FILE  NETBEANS将会编译文件,会弹出浏览器浏览该页,将地址栏改为http://localhost:8084/JF/gateway 回车,如果浏览器自动跳转到http://localhost:8084/flashservices/index.html 则证明配置成功。

请参看照片栏位的NETBEANS & Remoting中的内容。

Dtd(资料)

最近在深入研究FLASH REMOTING与JAVA的结合,遇到许多需要深入的知识,查到一些资料,粘上来,供大家学习,很基础但很好懂!

级别: 初级

IBM, 作者

2003 年 3 月 01 日


个“有效的”文件首先应该是“形式良好”的。但这还远远不够,它还要往前更进一步。一个XML文件必须遵守文件类型描述Dtd(Document
Type Definition)中定义的种种规定。所有的文件都是由序言和文件体构成的。序言中包含了XML声明,在序言中还可以包含Dtd定义。

内部Dtd

一个“有效的”文件首先应该是“形式良好”的。但这还远远不够,它还要往前更进一
步。一个XML文件必须遵守文件类型描述Dtd(Document Type Definition)中
定义的种种规定。所有的文件都是由序言和文件体构成的。序言中包含了XML声明,
在序言中还可以包含Dtd定义。

最简单的使用Dtd的方法是在XML文件的序言部分加入一个Dtd描述,加入的位置是
紧接在XML处理指示之后。一个包含Dtd的XML文件的结构为:


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<?DOCTYPE 根元素名[
元素描述
]>
文件体.......

这样,我们就定义了一个文件,它以DOCTYPE中规定的根元素名作为其根元素的名字。

如果为每一个XML文件加入一段Dtd定义,是相当繁琐的。而且,更多的情况下,我们
会为一批XML文件定义一个相同的Dtd。例如,对于报社中的每篇稿件,它们都有相同
的格式,可以采用一个统一的Dtd,为每一篇单独定义既麻烦,又不利于统一格式。
好在XML规范为我们提供了解决这个问题的方法,它就是外部Dtd。


v

外部Dtd的好处是:它可以方便高效地被多个XML文件所共享。你只要写一个Dtd
文件,就可以被多个XML文件所引用。事实上,当许多组织需要统一它们的数据交
换格式时,它们就是通过外部Dtd来完成的。这样做不仅简化了输入工作,还保证
当你需要对Dtd做出改动时,不用一一去改每个引用了它的XML文件,只要改一个
公用的Dtd文件就足够了。

为了引用一个外部Dtd,必须修改XML声明和DOCTYPE声明。

XML声明中必须说明这个文件不是自成一体的,即standalone属性的属性值不再是yes了:


<?xml version = "1.0" encoding="Gb2312" standalone = "no"?>

在DOCTYPE声明中,应该加入SYSTEM属性:<!DOCTYPE 根元素名 SYSTEM "外部Dtd文件的URL">

例如:


<!DOCTYPE 联系人列表 SYSTEM "http://www.mydomain.com/dtds/fclml.dtd">

上面的URL是一个绝对路径,除此以外,它还可以是一个相对路径,如:
<!DOCTYPE 联系人列表
SYSTEM "fclml.dtd">
它说明这个Dtd文件和引用它的XML文件在同一个目录下。

使用这种方法,你可以方便地把Dtd文件从你的XML文件中分离出来,粘贴到另一
个文件fclml.dtd中。这样,你就得到一个Dtd文件和一个有效的XML文件。


公用Dtd

使用外部Dtd时,要在DOCTYPE中使用关键字SYSTEM。实际上,SYSTEM不是引
用外部Dtd的唯一方法,这个关键字主要用于引用一个作者或组织所编写的众多
XML文件中通用的Dtd。还存在一种外部Dtd,它是一个由权威机构制订的,提供
给特定行业或公众使用的Dtd。因此,另一个引用外部Dtd的办法是使用关键字
PUbLIC,引用这一类公开给公众使用的Dtd。

当使用关键字PUbLIC进行引用时,这个外部Dtd还需要得到一个标识名。引用公
共Dtd的形式为:

<!DOCTYPE 根元素 PUbLIC "Dtd名称" "外部Dtd的URL">

请见下面例子:


<!DOCTYPE 联系人列表 PUbLIC "联系人Dtd" "http://www.mydomain.com/dtds/fclml.dtd">

这个Dtd标识的命名规则和XML文件的命名规则稍有不同。具体地说,Dtd名称只能
包含字母、数字、空格和下面的符号:_%$#@()+:=/!*;?。同时,Dtd名称还必须
符合一些标准的规定。例如,ISO标准的Dtd以“ISO”三个字母开头;被改进的非ISO
标准的Dtd以加号“+”开头;未被改进的非ISO标准的Dtd以减号“-”开头。

无论是哪一种情况,开始部分后面都跟着两个斜杠“//”及Dtd所有者的名称。在这个
名称之后又是两个斜杠“//”,再然后是Dtd所描述的文件的类型。最后,在又一对斜
杠之后是语言的种类(参见ISO 639)。例如下面这个公用Dtd的引用:


<!DOCTYPE 联系人列表 PUbLIC "-//Luna Dong//Contact Data//CN" "http://www.mydomain.com/dtds/fclml.dtd">

看上去的确比较复杂,不过没关系,对于Dtd的命名通常不是它的引用者的任务,XML
文件的编写者只要在自己的文件中把事先定义好的Dtd名称放在相应的位置中就可以了。


元素类型声明1

一个Dtd不仅要告诉语法分析器它所关联的XML文件的根元素是什么,而且还要告
诉语法分析器文件的内容和结构,说清文件结构中的每一个细节。为了定义这些细
节,我们必须展开Dtd中元素说明部分,使用元素类型声明(Etd)来声明所有有
效的文件元素。

Etd不但说明了每个文件中可能存在的元素,给出了元素的名字,而且给出了元素的
具体类型。一个XML元素可以为空,也可以是一段纯文本,还可以有若干个子元素,
而这些子元素同时又可以有它们的子元素。Dtd正是通过元素之间的父子关系,描述
了整个文件的结构关系。

Etd应该采用如下的结构:
<!ELEMENT 元素名 元素内容描述>

因此,在前面的例子里,可以在文件序言中通过如下方式定义“联系人列表”这个元素:


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
]>

<联系人列表>
...
</联系人列表>

这个Dtd定义了一个XML文件,它只有一个根元素,名为“联系人列表”,这个元素可以
有任何类型的子元素,也可以是纯文本,还可以为空。

但是需要注意,尽管元素“联系人列表”被定义为“可以”包含其它元素,但实际上这个
Dtd除了“联系人列表”元素本身外没有定义任何其它元素,所以也就没有其它元素可
以用作“联系人列表”的子元素。“有效的”XML文件规定文件中所使用的任何元素都必
须在Dtd中给出定义。

在“ANY”定义下使用任何纯文本都是无须另加说明的,这一点与元素不同。故而,在
相同的Dtd定义下,下面一段XML文件则是合法的:


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
]>

<联系人列表>
纯文本信息说明联系人信息
</联系人列表>

元素类型声明2

为了使元素“联系人列表”中还可以包含其它元素,从而使前面的那个文件是“有效 的”,我们还需要定义元素“联系人”和“姓名”。


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名)>
<!ELEMENT 姓名(#PCDATA)>
]>

<联系人列表>
<联系人>
<姓名>张三</姓名>
</联系人>
</联系人列表>

现在我们已经定义了一个XML文件,它的根元素名为“联系人列表”。“联系人列表”
中可以包含任何纯文本数据,也可以含有子元素(这即是ANY的含义)。根据后面的
定义,我们知道,“联系人列表”中可以包含子元素“联系人”,也可以直接包含子元
素“姓名”;“联系人”元素又可以包含自己的子元素,名为“姓名”;而“姓名”则只能
包含纯文本数据(即(#PCDATA))。

注意:

  1. 除了根元素外,在定义其它元素时使用关键字ANY都是不好的习惯。
  2. 在定义元素时,Etd的顺序是无关紧要的。
  3. 还有一点要注意,不能对不同的元素使用相同的元素名,即便这些元素的内容、包
    含的子元素不同也不行,因为它只会引起文件各个元素的混淆,使文件的可读性大打
    折扣。
  4. 元素名的第一个字母必须是字母、或下划线(_)、或冒号(:),后跟字母、数
    字、句号(.)、冒号、下划线、连结号(-)的组合,并且不能包含空白符,不能以
    “xml”开头。尽管XML1.0标准允许使用任何长度的文件名,但是实际的XML处理器常
    常会限制标记名的长度。


定义元素及其子元素

对于以下的例子:


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名)>
<!ELEMENT 姓名(#PCDATA)>
]>

<联系人列表>
<联系人>
<姓名>张三</姓名>
</联系人>
</联系人列表>

准确的说法是,元素“联系人”必须包含一个,且只能包含一个子元素“姓名”。可如
果子元素是“EMAIL地址”怎么办?联系人可能根本没有自己的EMAIL邮箱,也可能
有好几个EMAIL帐号。

使用正则表达式,我们就可以解决上述问题,描述父元素与子元素之间非常复杂的
关系。例如,你可以对一个元素作如下任何一种类型的定义:它有一个子元素,有
一个或多个子元素,有零个或多个子元素,至少有一个子元素。你还可以定义复合
关系,比如“元素X是有效的,如果它含有一个或多个子元素Y,或一个子元素Z”。

元素定义是由它们的元素内容模型(ECM)来描述的,也就是说,是由紧跟元素后
面的括号中的内容来定义的。因此,正如我们前面见到的,元素“联系人”的ECM被
描述为子元素“姓名”:
<!ELEMENT 联系人(姓名)>

ECM中的内容采取一组正则表达式的形式。在下表中,我们列出了正则表达式中可能出现的元字符:

元字符 含义
+ 出现一次或多次
* 出现零次或多次
可选,不出现或出现一次
() 一组要共同匹配的表达式
| OR,或,AND 要求严格遵从顺序要求

下面几节中,我们将通过一些例子具体讲解这些元字符的用法,对使用正则表达式
来定义ECM的方法获得一些感性认识。


有顺序的子元素

一个元素的各个子元素之间可以以任意顺序出现,也可以强制遵循一定的顺序。

考虑下面的Dtd定义:


<!ELEMENT 联系人(姓名 EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>

遵从这个Dtd的XML文件可以为:


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
</联系人>

同样,下面这个XML文件也是有效的:


<联系人>
<EMAIL>zhang@aaa.com</EMAIL>
<姓名>张三</姓名>
</联系人>

由于我们在Dtd定义中仅仅用空白符分隔了元素“联系人”的两个子元素,这说明
我们并没有严格要求两个元素出现的顺序,因此上面两种写法都是允许的。如果
我们使用逗号“,”来分隔两个子元素,那么XML文件中,元素“姓名”就必须出现
在元素“EMAIL”前面。


重复元素

让我们再把上节的例子作一个小小的改动:


<!ELEMENT 联系人(姓名,EMAIL+)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>

让我们看看前面给出的正则表达式的元字符集列表,它说明一个“联系人”元素中必
须含有一个“姓名”元素,后面接一个或多个“EMAIL”元素。这样,下面的这段XML
文件是“有效的”。


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
<EMAIL>zhang@hotmail.com</EMAIL>
<EMAIL>zhang@yahoo.com</EMAIL>
</联系人>

那么下面这段XML文件不是有效的,因为它没有“EMAIL”元素,而“+”代表了“一个
或多个”。


<联系人>
<姓名>张三</姓名>
</联系人>

如果你需要表示“零个或多个”,那么应该使用字符“*”。例如:


<!ELEMENT 联系人(姓名,EMAIL*)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>

回页首

成组元素

子元素可以使用括号并为一组。因此,下面的Dtd片段说明,一个“联系人”元素
中可以有一个或多个“姓名/EMAIL”子元素对,并且在每个子元素对中,“姓名”都
放在“EMAIL”之前。


<!ELEMENT 联系人(姓名,EMAIL)+>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>

符合这个Dtd的XML文件可以是:


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>

<姓名>李四</姓名>
<EMAIL>li@bbb.org</EMAIL>

<姓名>王五</姓名>
<EMAIL>wang@ccc.org</EMAIL>
</联系人>

注意,仅仅是因为“+”由括号里面移到括号外面,元素“联系人”的内容就大大不同了。


OR或

号“|”描述了一个OR操作。因此,下面的Dtd片段所规定的XML元素是:所有的
“联系人”元素应该有一个“姓名”子元素,同时,在此之后还应该有一个“电话”或
一个“EMAIL”元素,但不能同时有“电话”和“EMAIL”两个元素。


<!ELEMENT 联系人(姓名,(电话|EMAIL))>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT 电话(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>

一个符合上述Dtd定义的“有效的”XML文件的定义应该是:


<联系人>
<姓名>张三</姓名>
<电话>12345678</EMAIL>
</联系人>

或者是:


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@yahoo.com</EMAIL>
</联系人>

注意:在一个组中,只允许使用一种连接符(例如“,”或“|”)。因此,象下面这样定义的Dtd是不合法的:<!ELEMENT 联系人(姓名,电话|EMAIL)>

要想使用多种连接符,只有通过创建子组的方式,使用<!ELEMENT 联系人(姓名,(电话|EMAIL))>


回页首

可选子元素

字符“?”说明一个子元素是可选的,它可以出现,也可以不出现。因此,在下面的Dtd
中,我们规定,每一个“联系人”都必须有一个“姓名”子元素,同时或者有一个“电话”
子元素,或者有一个“EMAIL”子元素,此外,它还可以包含一个“地址”子元素,也可
以不包含这种元素。


<!ELEMENT 联系人(姓名,(电话|EMAIL),地址?)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT 电话(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ELEMENT 地址(街道,城市,省份)>
<!ELEMENT 街道 (#PCDATA)>
<!ELEMENT 城市 (#PCDATA)>
<!ELEMENT 省份 (#PCDATA)>

根据这个Dtd描述,下面的XML片段是“有效的”:


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
<地址>
<街道>五街1234号</街道>
<城市>北京市</城市>
<省份>北京</省份>
</地址>
</联系人>

同样,下面这段不包含“地址”元素的XML片段也是“有效的”:


<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
</联系人>

回页首

混合内容&空元素

当然,可能也有一些时候,你在一个元素中既希望包含子元素,也希望包含纯文本。
XML中允许这种使用方法,并把这种元素称为混合内容的元素。在下面的例子中,
“联系人”就是一个混合元素。


<?xml version = "1.0" encoding="Gb2312" standalone = "yes"?>
<!DOCTYPE CONTACTS [
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名|电话|EMAIL|#PCDATA)*>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT 电话(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
]>
<联系人列表>
<联系人>
<姓名>张三</姓名>
<电话>(010)62345678</电话>
<EMAIL>zhang@aaa.com</EMAIL>
这是关于张三的信息
</联系人>
</联系人列表>

注意,由于在“(姓名|电话|EMAIL|#PCDATA)”之外有“*”,所以在元素“联系人”中可以包含零个或多个“姓名”、电话、EMAIL和纯文本字段。

还有一种情况没有说,那就是,一个元素中不包含任何子元素,也不包含纯文本。对于这种情况,我们可以定义一个空标记。当然,定义这样一个标记很简单,你只需
要使用关键字EMPTY就可以了,例如:<!ELEMENT HR EMPTY> 这样,在你的XML文件中,就可以使用一个空元素<HR/>。


回页首

定义有效的元素属性

现在我们已经学会如何定义一个元素以及它的内容,如何描述父元素与子元素之间
错综复杂的关系,只差不知道如何定义元素的属性了。

在第二篇教程中我们曾经提到过属性,那个例子是一个有关“商品”的元素,它有两个属性,即“类型”和“颜色”:<商品 类型 = "服装" 颜色 = "黄色">

在Dtd中定义属性时,我们使用下面的格式: <!ATTLIST 元素名 (属性名 属性类型 缺省值)*>


素名是属性所属的元素的名字,在上面例子中,元素名是“商品”;属性名是属性的命名,例子中,“类型”和“颜色”是属性名;缺省值说明在XML文件中,如
果没有特别说明属性的取值,语法分析器默认它具有的取值;属性类型则用来指定该属性是属于十个有效属性类型中的哪种类型。

注意:由于ATTLIST是一个属性的列表,它可以包含很多属性,在实际应用中,一个元素也经常有多个属性。

上面例子中的属性可以如下定义:


<!ATTLIST 商品
类型 CDATA #REQUIRED
颜色 CDATA #IMPLIED
>

在元素说明的四个部分中,我们需要再详细讨论一下元素类型和缺省值。在下一节中,我们就从缺省值说起。


回页首

属性缺省值

根据XML文件是否必须为一个属性提供取值,属性的缺省值又可以分为以下三类:

  1. 必须赋值的属性

    关键字REQUIRED说明XML文件中必须为这个属性给出一个属性值。例如,假设你
    想定义一个"页面作者"元素,并把这个元素加入所有网站中的每一个页面。之所
    以定义这个元素,是为了页面编辑者能够提供他的联系信息,以便当发现页面错
    误或无效链接时,可以及时地通知他。在这种情况下,每个页面作者都有不同的
    个人信息,所以你无法事先知道应该用什么作为缺省值,但你又的确需要提供每
    个人的信息。这时候,你就可以把与联系信息相关的属性定义为必须的
    (REQUIRED),而且不用提供缺省值。

  2. 属性值可有可无的属性

    当使用IMPLIED关键字时,文法解释器不再强行要求你在XML文件中给该属性赋
    值,而且也无须在Dtd中为该属性提供缺省值。可以说,这是对属性值有无的最
    低要求,现实中经常用到。

  3. 固定取值的属性

    还有一种特殊情况,你需要为一个特定的属性提供一个缺省值,并且不希望XML
    文件的编写者把你的缺省值替代掉。这时候,就应该使用FIXED关键字,同时为
    该属性提供一个缺省值。

  4. 定义缺省值的属性

    如果不使用上面任何一种关键字的话,该种属性就是属于这种类型。对于这种属
    性,你需要在Dtd中为它提供一个缺省值。而在XML文件中可以为该属性给出新的
    属性值来覆盖事先定义的缺省值,也可以不另外给出属性值,后一种情况下它就
    默认为采用Dtd中给出的缺省值。

至于究竟采用哪种缺省值,就看实际需要了。下面给出一个具体的例子:


<!ATTLIST 页面作者
姓名 #CDATA #IMPLIED
年龄 #CDATA #IMPLIED
联系信息 #CDATA #REQUIRED
网站职务 #CDATA #FIXED "页面作者"
个人爱好 #CDATA "上网">

回页首

属性类型

一个元素可以为以下十种类型中的任意一种:


CDATA
Enumerated
ID
IDREF
IDREFS
ENTITY
ENTITIES
NMTOKEN
NMTOKENS
NOTATION

下面我们就来一个一个讲述。


回页首

CDATA类型

CDATA指的是纯文本,即由字符、符号“&”、小于号“<”和引号“"”组成的字符串。
当然,就象我们前面讲到的,你应该使用实体&代替“&”,<代替“<”,
"代替“"”。

请看下面这个关于剧本的例子:


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 剧本 [
<!ELEMENT 剧本 ANY>
<!ELEMENT 对话 (#PCDATA)>
<!ATTLIST 对话 演员 CDATA>
]>
<剧本>
<对话 演员="某甲">我可不这么认为!</对话>
<对话 演员="某乙">为什么呢?</对话>
</剧本>

回页首

枚举类型

属性也可以被描述为一组可接受的取值的列表,XML文件中对属性的赋值将从这个列表中选取一个值。这类属性属于枚举类型ENUMERATED,不过,关键字ENUMERATED是不出现在Dtd定义中的。


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 购物篮 [
<!ELEMENT 购物篮 ANY>
<!ELEMENT 肉 EMPTY>
<!ATTLIST 肉 类型( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">
]>
<购物篮>
<肉 类型 = "鱼肉"/>
<肉 类型 = "牛肉"/>
<肉/>
</购物篮>

注意,在上面这个例子中,给属性“类型”定义的缺省值是“鸡肉”,所以“购物篮”中的第三个元素的“类型”属性取值为“鸡肉”。


回页首

ID和IDREF

ID类型

ID是用属性值的方式为文件中的某个元素定义唯一标识的方法,它的作用类似于
HTML文件中的内部链接。在大多数情况下,ID由处理文件的程序或脚本语言使用。

ID的值必须是一个有效的XML名称,它由字母、数字或下划线开始,名字中不能出
现空白符。另外一般而言,不要给ID类型的属性事先指定缺省值,这很容易引起不
同的元素具有相同的标识的情况,更不能使用FIXED型的缺省值。此类属性经常使
用REQUIRED缺省类型,当然,这也不是必须的。有的应用并不要求每个元素都有
自己的标识,所以,也可以使用IMPLIED缺省类型。


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名,EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ATTLIST 联系人 编号 ID #REQUIRED>
]>

<联系人列表>
<联系人 编号="1">
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
</联系人>

<联系人 编号="2">
<姓名>李四</姓名>
<EMAIL>li@bbb.org</EMAIL>
</联系人>
</联系人列表>

回页首

ID和IDREF2

IDREF类型

IDREF类型允许一个元素的属性使用文件中的另一个元素,方法就是把那个元素的
ID标识值作为该属性的取值。例如下面的例子:


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名,EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ATTLIST 联系人 编号 ID #REQUIRED>
<!ATTLIST 联系人 上司 IDREF #IMPLIED>
]>

<联系人列表>
<联系人 编号="2">
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
</联系人>

<联系人 编号="1" 上司="2">
<姓名>李四</姓名>
<EMAIL>li@aaa.com</EMAIL>
</联系人>
</联系人列表>

回页首

NMTOKEN和NMTOKENS

类型NMTOKEN和NMTOKENS是诸多属性类型中面向处理程序的又一个类型。这两个
类型用于指示一个有效的名字。当需要把一个元素和其它的元件,例如一个JAVA
类或一个安全算法,相联系时,可以让它们助你一臂之力。请看下面的例子:

关于元素的定义:


<!ELEMENT 数据(#PCDATA)>
<!ATTLIST 数据
安全性( ON | OFF ) "OFF"
授权用户 NMTOKENS #IMPLIED
>

XML文件:


<数据 安全性="ON" 授权用户 = "Iggieeb SelenaS Guntherb">
blah blah blah
</数据>

回页首

NOTATION类型

NOTATION类型允许属性值为一个Dtd中声明的符号,这个类型对于使用非XML格式的数据非常有用。

现实世界中存在着很多无法或不易用XML格式组织的数据,例如图象、声音、影象等
等。对于这些数据,XML应用程序常常并不提供直接的应用支持。通过为它们设定
NOTATION类型的属性,可以向应用程序指定一个外部的处理程序。例如,当你想要
为一个给定的文件类型指定一个演示设备时,可以用NOTATION类型的属性作为触发。

要使用NOTATION类型作为属性的类型,首先要在Dtd中为可选用的记号作出定义。
定义的方式有两种,一种是使用MIME类型,形式是:

<!NOTATION 记号名 SYSTEM "MIME类型">

再有一种是使用一个URL路径,指定一个处理程序的路径。

<!NOTATION 记号名 SYSTEM "URL路径名">

在下面这个例子中,为"电影"元素指定了两种可选设备:一种是movPlayer.exe,用来播映.mov文件,另一种则用来绘制GIF图象。


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 文件[
<!ELEMENT 文件 ANY>
<!ELEMENT 电影 EMPTY>
<!ATTLIST 电影 演示设备 NOTATION ( mp | gif ) #REQUIRED>
<!NOTATION mp SYSTEM "movPlayer.exe">
<!NOTATION gif SYSTEM "Image/gif">
]>

<文件>
<电影 演示设备 = "mp"/>
</文件>

回页首

实体属性类型与参数实体

实体在XML中充当着宏或别名的角色。实体最根本的作用是帮助你为一大段文本创
建一个别名,这样,在文件的另一个位置需要引用这段文本时,仅需要指向它的别
名就可以了。它还意味着一旦需要修改,仅需要在一个地方作改动,就完成了全局
的改动。

我们还提到,实体分为一般实体和参数实体两种类型,它们都可以定义为内部的也
可以用关键字SYSTEM定义为外部的。实体的定义必须出现在引用之前,而且要注意
正确嵌套,不能出现循环引用的情况。在Dtd中,这两种类型的实体都得到了广泛的
应用。

实体属性类型

实体类型的属性值属于一般实体,如前所述,它的定义方式是:
<!ENTITY 实体名 "实体内容">

或利用SYSTEM定义外部实体,方式为:
<!ENTITY 实体名 SYSTEM "外部文件名">

引用方式为:
&实体名;

使用关键字ENTITY,则声明一个属性是实体类型,它的取值为已定义的实体。请看下面例子:


<?xml version = "1.0"
encoding="Gb2312"
standalone = "yes"?>
<!DOCTYPE 文件[
<!ELEMENT 文件 ANY>
<!ELEMENT 电影 EMPTY>
<!ATTLIST 电影 来源 ENTITY #REQUIRED>
<!ENTITY bladeRunner SYSTEM "dvds/bR/br.mov">
]>

<文件>
<电影 来源 = "&bladeRunner;">
</文件>

参数实体
参数实体专门用在Dtd中。定义方式是:
<!ENTITY % 实体名 "实体内容">

或:
<!ENTITY % 实体名 SYSTEM "外部文件名">

引用方式为:
%实体名;
使用参数实体,可以方便元素和属性的声明。例如:


<!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址">
<!ELEMENT 个人联系信息 (%TAG_NAMES; | 生日)>
<!ELEMENT 客户联系信息 (%TAG_NAMES; | 公司名)>

最后提醒大家注意,不要以为实体属性类型的定义与Dtd有关,所以它使用的就是参数
实体。参数实体只能在Dtd中使用,而对于任何元素属性值的指定(除了缺省值外),
都是在XML文件正文中进行的,因此实体属性值仍属于一般实体。


回页首


回页首

关于作者

IBM has authored this article

解码 XML 和 DTD(资料)

未显示需要 JavaScript
的文档选项

级别: 初级

Jane Fung, VisualAge for Java 支持, IBM 加拿大

2001 年 7 月 01 日


篇介绍性文章说明了如何创建 XML“文档类型定义(DTD)”和格式正确定义明确的 XML 文件,这些文件能够由您选择的 XML
语法分析器进行确认。虽然不必在产生的每个 XML 文件中都包含 DTD,但这样做将会使您的生活大为轻松。DTD 不仅强制使用为 XML
文件建立的语法,它还将允许文件由确认 XML 语法分析器进行语法分析。代码样本包括 DTD 和 XML 文档示例。

“可扩展标记语言”已经存在了十分长的一段时间,因此现在大多数人都熟悉其最基本的需求:所有
XML 文档都必须既格式正确又有效。但如何确定您的 XML
文档是否满足这些需求呢?简短的回答就是您不用确定。或者至少是不必。大多数时候,您会依赖于
XML 语法分析器来为您管理这些苦活。

在经过一些小调查(请参阅

参考资料)后您就会发现市场上到处充斥着 XML
语法分析器,其中大多数都可以从 Web 上免费获得。一个基本的 XML
语法分析器既强调 XML
语法规则(即,确保文件格式正确),又建立文件的有效性。XML
语法分析器可用于几乎每种相关的计算机语言,包括
C、C++、Perl、Python、Tcl 和 Java。

谈到确保 XML
格式正确时,您可以或多或少地指向一个语法分析器然后执行。然而为了确保文档有效,需要为语法分析器提供文档类型定义或
DTD。

模式如何?

最近,W3C 将长期以来一直讨论的 XML Schema
规范推进成“建议书”状态,这意味着它有可能为开发人员普遍所用。在某些方面,XML
Schema 将替代 DTD。而在其它方面,DTD 仍是最好的解决方案。有关解释
XML Schema,以及将它与 DTD 进行功能和处理上的对比的 developerWorks
文章,请参阅

参考资料

本文回顾了 XML
文档格式正确究竟意味着什么,然后会谈到较少讨论的话题确认 -
更具体地说,是 DTD。我将讨论为什么您需要将 DTD 包含在 XML
文件中、介绍一些最常用的 DTD
语法,并使用几个简单的样本来教您开始编写自己的 DTD。

为什么要格式正确?

当 XML 开发人员谈到格式正确和格式不正确的 XML
时,我们并不是参加美学讨论。当然,格式正确的 XML
文档是满足以下三个基本结构需求的文档:

  • 有一个包含所有其它元素的父(或根)元素
  • 每个开始标记都有结束标记
  • 所有元素都正确嵌套的

清单 1 是一个格式正确的 XML 示例。请注意:该文档的父元素是

<person> ,每个开始标记都有一个结束标记,并且每个结束标记都有与其开始标记完全相同的定义。通常,开始标记和结束标记之间包括的是信息或文本。不过,在某些情况下,标记之间没有包括信息或文本。空标记必须用一个右斜杠来结束。


<nothing/>
就是一个空标记。

清单 1. 格式正确的 XML

<person>
<firstname>Jane</firstname>
<lastname>Fung</lastname>
<nothing/>
</person>

清单 2 是一个格式不正确的 XML
示例。它举例说明了三种常见错误。首先,开始和结束

<firstname>
标记没有完全匹配。其次,

<lastname>
标记没有结束标记。最后,空标记没有用一个右斜杠结束。

清单 2. 格式不正确的
XML

<person>
<Firstname>Jane</firstname>
<lastname>Fung
<nothing>
</person>

回页首

DTD
中有什么内容?

XML
的优点在于它允许您定义自己的有意义的标记,因此您可以最大程度地定制文档。但
XML 就是
XML(可扩展),而人就是人(疯狂的人),这可能很快就会无法控制。解决方案是
DTD,它指定了 XML 文档的标记。简而言之,DTD
指定:可以在文档中存在的元素、那些元素可以具有的属性、在元素内部元素的层次结构以及元素在整个文档中出现的顺序。

虽然 DTD 不是必需的,但它们确实带来方便。DTD
适合三个基本用途。它能:

  • 对标记编制文档
  • 加强标记参数内部的一致性
  • 使 XML 语法分析器能够确认文档

如果不对 XML 文档进行 DTD 定义,文档就无法由 XML
语法分析器进行确认。使用 XML Schema 实例来代替 DTD
如何?(请参阅侧栏

模式如何?)清单 3 是清单 1
中显示的 XML 文档的 DTD。

清单 3. 精简 person.xml 的
DTD

<!ELEMENT person (firstname, lastname)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT nothing EMPTY>

关于示例的几点说明

清单 3 中 DTD 的第一行定义了 XML
文档的父元素:

person 。person
元素有两个子元素:

firstname

lastname

第二和第三行包含了元素属性

#PCDATA ,它表明

firstname

lastname
元素可能包含经过语法分析的字符数据(在这种情况下是文本)。DTD
文件的最后一行描述了一个空标记:

nothing

从清单 3 中的 DTD 可以看出,任何阅读我们的 XML
文档的人(以及对它进行语法分析的语法分析器)都知道

person 元素仅包含两个文本元素:

firstname

lastname 。此外,DTD
规定,在整个文档中,

firstname 元素必须在

lastname 元素之前出现。

在转到更复杂的示例之前,让我们回顾一下一些最常用的 DTD
语法元素。可以在 W3C 主页上找到完整的 DTD 规范(请参阅

参考资料)。


回页首

DTD
语法快速指南

A、B、C 和 D 是在下例中代表元素的变量。

元素必须有正好一个

A 、至少一个

B (由加号表示)、零个或多个

C (由星号表示)以及零个或一个

D (由问号表示):

<!ELEMENT element (A, B+, C*, D?)>

元素可能有

A

B

C
之一:

<!ELEMENT element (A | B | C)>

元素不包含任何内容:

<!ELEMENT element EMPTY>

元素可以包含在 DTD 中列出的任何元素:

<!ELEMENT element ANY>

元素可能包含经过语法分析的字符数据或另一个元素(

element2 )。星号(*)表示混合内容模型 — 其中元素可以包含不同类型的属性。

<!ELEMENT element (#PCDATA|element2)*>

下例将文本 "entity reference" 插到文档中它出现的任何地方:

<!ENTITY element "entity reference">

可以看到在 XML 文档中该实体引用元素如下:

&element;

下例表明其元素是一个包含三个属性的空标记:属性
1(

att1 )是一个可选属性,属性
2(

att2 )是带有固定值

"A" 的属性,属性
3(

att3 )是必需的文本属性。

   <!ELEMENT element EMPTY>


<!ATTLIST element
att1 ID #IMPLIED
att2 CDATA #FIXED "A"
att3 CDATA #REQUIRED>


可以看到在 XML 文档中使用的这个元素如下:

<element att2="A" att3="MustHave"/>

属性

CDATA
表示包括的信息应该是文本。

ID
属性表明必须填入唯一的标识。每个元素只能有一个

ID
属性。另外,

CDATA 表示

att2

att3 可能包含任何字符串。

如果您对该语法还未完全熟悉,请继续阅读。下一部分中的工作示例应该能帮助您消除疑虑。


回页首

工作示例

可以使用 Microsoft Internet Explorer 5 或更高版本查看清单 4
中显示的 XML 文档 ― 前面示例中使用的 people.xml
文件的扩展版本。如果在 IE5 中打开
people.xml,应该看到一个树结构。这是因为 IE5 带有能够将 XML
文档语法分析成元素树的 XML 语法分析器。

还可以在

参考资料中找到这个文件及其
DTD。

清单 4. people.xml
的完整清单

<?xml version="1.0"?>
<!DOCTYPE people SYSTEM "people.dtd">
<people>
<person>
<name>
<firstname>Jane</firstname>
<lastname>Fung</lastname>
</name>
<look>good-looking</look>
<possession>
<car>
<model>Civic</model>
</car>
<job>&IBM;</job>
</possession>
</person>
<person>
<name>
<firstname>G.I.</firstname>
<lastname>Jane</lastname>
</name>
<look>tough</look>
<possession>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
<bankaccount bankaccount_number="sg-123">

<![CDATA[<greeting>5000</greeting>]]>
</bankaccount>
</possession>
<other>
<car>she has a car</car>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
</other>
</person>
</people>

关于 XML 的几点说明

对 XML 的深入探讨主要考虑的是文档头中的几个元素,从以下开始:

<?xml version="1.0"?>

每个 XML 文档都必须包含这样的一个头,向 XML
语法分析器表示它是一个 XML 文档。头中的下一行告诉 XML
语法分析器该文档是使用什么字符编码来创建的:

<!DOCTYPE people SYSTEM "people.dtd">

在 Unix 系统上创建的 XML 文档和在 Windows 系统上创建的 XML
文档可能有不同的编码。

还可以为第一行设置可选的

standalone
属性。standalone 的缺省值是

no

no 值表示该 DTD
定义是在另一个文件中描述的。

yes 值表明该 DTD 应该在 XML
文档内部定义。我没有为示例设置这个属性;如果想设置,它应该看起来如下:

   <?xml version="1.0" standalone='yes'?>
<!DOCTYPE people [
<!ELEMENT people (person+)>
<!ELEMENT person (#PCDATA)>
]>

还应该注意使这个文档格式正确的方法。例如,所有空标记都用一个右斜杠结束,如下所示:

<townhouse townhouse_type="good" />

还请注意

CDATA 用于对所有若不进行转义就会以 XML 语言解释的任何数据进行转义,例如:

<![CDATA[<greeting>5000</greeting>]]>

如果适当的格式化,这一行将以文本内容显示:

<greeting> 5000 </greeting>

可以从 XML 文件的进一步研究中获益,甚至可能从对您自己的文件运行
XML 语法分析器获益(请参阅

参考资料)。但是现在,让我们看一下 people.xml
文件的 DTD。

清单 5. people.dtd
的完整清单

<!ELEMENT people (person+)>
<!ELEMENT person (name, look*, possession?, other?)>
<!ELEMENT name (firstname, lastname)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT look (#PCDATA)>
<!ELEMENT possession (car?, house?, bankaccount?, job?)>
<!ELEMENT car (#PCDATA|model)*>
<!ELEMENT model (#PCDATA)>
<!ELEMENT house (apartment|standalone|townhouse)>
<!ATTLIST house house_area ID #IMPLIED country CDATA #FIXED
"CANADA" city CDATA #IMPLIED>
<!ELEMENT apartment EMPTY>
<!ELEMENT standalone EMPTY>
<!ELEMENT townhouse EMPTY>
<!ATTLIST townhouse townhouse_type ID #IMPLIED>
<!ELEMENT bankaccount (#PCDATA)>
<!ATTLIST bankaccount bankaccount_number ID #REQUIRED>
<!ELEMENT job (#PCDATA)>
<!ELEMENT other ANY>

<!ENTITY IBM "Proud to work for IBM">

关于 DTD 的几点说明

使用

快速指南作为参考,通过比较 XML 文件及其
DTD,您应该能够方便地定义 DTD 和 XML
文件中各元素之间的关系。不过,还有两个剩下的元素,您可能感兴趣。

清单 4 包含了对实体的引用。

<job>&IBM;</job>

实体引用用于代替在 DTD
文档中定义的特定字符或字符串。进行了语法分析后,该实体引用将读作:

<job> Proud to work for IBM </job>

还应该注意,

<other> 标记的内容类型是

ANY 。这表示

<other>
可能包含所有以前已在 DTD 中声明过的元素。因此,

other
元素可能包含

car

house
元素,如下:

   <other>
<car>she has a car</car>
<house country="CANADA" city="Toronto">
<townhouse townhouse_type="good" />
</house>
</other>

回页首

结束语

这就结束了对创建格式和定义均正确的 XML
文件的基本介绍。您可能想要继续自己研究 people.xml 和 people.dtd
文件。如果想要尝试使用 XML
语法分析器对这些文件进行语法分析,请参阅“参考资料”来查找可供下载的语法分析器的列表。


回页首

参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的

    英文原文.

  • 如果希望了解有关 XML 和 DTD 语法的更多信息,

    XML
    1.0 W3C Recommendation
    应该是您的第一站。

  • Tim Bray 是 XML 1.0 规范的原始编辑之一。他维护着

    Textuality.com,可以在上面找到他关于
    XML、DTD 等内容思想。还可以找到 Lark 和 Larval,Bray 自己的 XML
    语法分析器。

  • Doug Tidwell 的


    教程:XML 简介
    展示了对“可扩展标记语言”近乎完整的探讨。

  • 您可能还想要仔细查看 Mark Johnson 在 JavaWorld 上发表的


    XML for the absolute beginner
    一文。

  • 请下载本文示例中使用的

    people.xml

    people.dtd文件,以进一步研究和分析。

XML 语法分析器:简表

  • IBM 的


    XML Parser for Java
    (XML4J),目前是版本 3.1.1,是以 100% 纯
    Java 编写的确认 XML 语法分析器。包(com.ibm.xml.parser)包含了对
    XML 文档进行语法分析、生成、操纵和确认的类和方法。

  • IBM 的


    XML for C++ parser
    (XML4C) 基于 Apache 的 Xerces-C XML
    语法分析器,它是用 C++ 的可移植子集编写的确认 XML 语法分析器。

  • XML::Parser
    是 Perl 扩展模块,充当与

    expat的接口。

  • TclXML
    是全 Tcl 的 XML 语法分析器。

  • Xerces 是来自
    Apache Software Foundation 的 Java 语法分析器,目前是版本
    1.4.0。

  • Lars Marius Goshol 负责维护作为公众服务的这个详尽的


    XML 语法分析器列表
    和其它 XML 工具。

相关链接

  • XML
    专区页面
    上查看最新信息。

  • 如同 DTD,在创建 XML
    文件时,样式表不是必需的,但如果希望控制浏览器中文档显示,它们就非常重要。Alan
    Knox 的 developerWorks 文章,

    Style sheets can
    write style sheets, too
    ,向您介绍如何使用 XSL 来将 XML
    数据转换成用于浏览器的复杂显示标记。

  • 阅读完上述文章后,可能想要查看 IBM alphaWorks 的


    XSL Editor

  • 如果希望探索 XML Schema 以及它与 DTD 的关系,请参阅 David Mertz
    在其 developerWorks 专栏“XML 问题 7”中的

    DTD 和 XML
    Schema 比较
    ,以及 Kevin Williams 的 developerWorks 临时讲台


    赞同使用 XMLSchema 的文章
    来了解用于数据的 XML
    文档的结构化定义。有关使用 XML Schema
    会怎样的简短说明,请参阅介绍性文章


    Basics of using XML Schema to define elements


回页首

关于作者

author

Jane Fung 目前在 IBM VisualAge for Java
技术支持小组工作,该小组为使用 VisualAge for Java
的企业开发人员提供支持。Jane
获得了加拿大安大略省的沃特卢大学电子工程应用科学学士学位,并且是一名
Sun Java 2 认证程序员。可以通过
jcyfung@ca.ibm.com 与 Jane
联系。


回页首

Flash & J2EE

这两天忙活着周六的网络工程师考试,所以空间里面一直没有时间更新。呵呵,一切为了明天,不过今天下午的时候还是忍不住找了些写资料,看到一篇热血沸腾的文章贴出来,不过当看到这篇文章发布的时间的时候,悍然了。下面全文引用,特此感谢翻译这篇文章的人。

–Flash远程调用提供了一种可选的J2EE表示层实现方法

翻译作者: yaojh302
原文作者:
Joseph Shomphe
原文链接: Enhance your J2EE presentation
layer

摘要:
对Macromedia公司的Flash的远程调用使得Java开发者除了JSP(JavaServer
Pages)和Swing之外又有了一种全新的方式来构建J2EE(Java 2 Platform, Enterprise Edition)应用.
本文调查了Flash远程调用,解释了为何它有如此作用,并且提供了一个如何实现的例子
(1800字, January 17,
2003)

在任何多层体系中选择表示层技术时,Java开发者通常有两种选择: JSP或者Swing/AWT(Abstract
Windowing
Tookit)。借助JSP,开发者可以创建非常容易发布的动态内容。但同时也使得当应用程序在不同的浏览器中发布时开发者不易控制他们的运行情况。使用Swing,开发者可以轻易控制应用程序的行为,但要求用户安装Java运行时环境。当开发者需要既以比较小,基于浏览器的方式发布同时又对用户的交互有较高的可控性时也存在这种情况。对于这些情况,Macromedia
Flash提供了一种可供选择的解决方法。
一般来说,Macromedia
Flash比发布界面丰富,带有脚本程序的应用程序要优越。不幸的是,直到最近都没有出现标准的方法可以将Flash应用整合进J2EE体系。这种状况随着Flash
Remoting MX的引入才得以改变。Flash Remoting MX提供了标准的通信层使Flash应用程序与Java,
.NET和ColdFusion之间进行通信。利用Flash
Remoting,开发者得以在J2EE体系中发布小的,基于浏览器的表示层,同时可以对应用的行为进行足够的控制。
本文将解释为何Macro
Flash适合于作为n层体系中应用层的解决方法。我将首先调查应用层如何得以改变,然后比较Flash和现有标准,最后解释Flash如何应用于J2EE体系。

应用层的演化:
从Berners-Lee创建第一个基于Web的系统至今,n层体系的表示层经历了一次变化。在那之前,开发者不得不开发与服务器紧密结合的客户端系统。所能利用的只有基本的HTTP协议,Web服务器和HTML,开发者可以为用户发布基于文档的应用系统,不管他们使用的是何种硬件或软件平台。这种方法对于应用层开发者有一些基本问题:
虽然HTML可以成功地被传送基于文档的数据,但它不适合有多种表现的应用—可与用户进行实时的交互。
为了解决这些不足,开发者开始在现代的浏览器(Netscape
Navigator
2.0以后)中开发一些新的特性,即Java和JavaScript。开发者第一次能够利用Web浏览器平台发布丰富的,与平台无关的应用。实际上Java小程序的使用从没有达到它的期望值。Java小程序要求用户已经安装Java运行时环境(Java
Runtime Environment,
JRE),并且Web浏览器安装了Java插件。除了需要安装客户端系统来运行Java小程序外,客户端还需下载Java小程序。这些是很耗费时间的,特别是会使Internet的连接变得非常慢。
除了这种解决方法外开发者有三种选择来在客户端/服务器应用中使用丰富的前端:
动态HTML(DHTML), applet/Swing, 或者第三方解决方法。每种解决方法都各有利弊。

DHTML:

使用DHTML创建丰富的前端提供了如下优点:
1. DHTML是开放的并且免费
2. 使用DHTML所写的应用可以在支持DHTML的任何Web浏览器中配置
3. 基于Web的应用其客户端通常都由文字和图片构成,这允许小的应用脚本的存在。

DHTML也并不总是一个好的解决方案;当选择这一技术时你也必须要考虑到它的一些缺点:
1.
DHTML依赖用户的Web浏览器来切实地将用户的原意反映在应用中。由于浏览器的厂家和版本多种多
样,因此复杂的应用中必须嵌入工作区以使得应用能够在不同的浏览器中有着同样的表现
2.
尽管DHTML使得开发者可以更好地控制客户端行为,但这种灵活性也是有限的
3.
由于不同的浏览器在表现HTML和解释JavaScript上有一些不同,必须为各个不同的Web浏览器创建
不同的平台。加入工作区并将每个浏览器的实现分开增加了维护应用的复杂性。另外,无论什么时候一
个新的浏览器发布后,应用(或应用的一个部分)就必须重新编码并测试。

当开发者明确知道他在标准的客户端配置什么样的应用时,使用DHTML的确有它的优势。如果企业内部网仅适用IE6.0,针对该浏览器的应用逻辑可以被处理得非常得当。

Applet/Swing:
对于Java开发者而言,基于applet或swing的解决方案是另外一种可行的解决方案。它有如下的优点:
1.
创建基于Java的应用无论对于用户还是开发者都是免费的
2. Applets可以通过大部分的浏览器进行配置
3.
Applets允许用户创建丰富的用户界面
4.
使用Applets让客户端分担了一部分服务器的负载
选择使用基于applets的解决方案也必须衡量它的以下不足:
开发者不能确定用户是否安装了JRE.
即便安装了,也不一定是所需要的版本。

Applets为开发者在标准客户端配置他们的应用提供了很大的选择余地。对于标准客户端,开发者可以假定正确的JVM版本已经安装

除了使用applet/Swing或DHTML应用,开发者还有一个选择:
第三方解决方案。

第三方解决方案: Mecromedia
Flash

为了达到DHTML或applet应用同样的效果,第三方产品需要具备以下特性:
1.
任何标准浏览器都可以使用它
2. 应用程序的运行几乎不需要用户的干涉
3. 客户端的运行时间必须是免费或者至少很便宜
4.
客户端应当可以与已有的业务逻辑结合在一起
有一些第三方解决方案在此领域共同竞争,包括Apple的QuickTime,
Microsoft的ActiveX,和Macromedia的Flash
Suite。所有这三种解决方案在许多用户的系统上都得到了使用。它们都能应用在基于Web浏览器的应用程序之中,而用户不需付出任何代价。然而相比于ActiveX和QuickTime,Flash为Java开发者提供了一个重大的助益:它允许客户端应用调用任何J2EE应用服务器上的方法。这就意味着已经存在的EJB,
servlets, Web services, 和类中的业务逻辑可以不作任何改变地被基于Flash的前端调用。
服务器端产品Flash
Remoting使得Flash客户端可以调用J2EE Server上的方法。Flash
Remoting由两个重要的部分组成:用于将本地的Flash对象和方法映射到Java对象和方法的网关服务器和客户端支持。网关应用在标准的war文件中,可在任何J2EE应用服务器中配置。客户端支持组成为ActionScript(被Flash运行和配置工具所使用的编程语言)增加的功能。
要让Flash
Remoting工作,Flash应用必须连接到J2EE
Server,获取它想要利用的服务(Java对象)的句柄并调用方法。这通过使用ActionScript库(NetServices)来做到。如下的例子与名为MX的Web应用中的网关连接,web.xml文件servlet映射如下:
<servlet-mapping>
<servlet-name>FlashGatewayServlet</servlet-name>
<url-pattern>/gateway</url-pattern>
</servlet-mapping>

//Load
the NetServices ActionScript Library
#include
"NetServices.as"

//Create a connection to the mx webapp running on
port 80 on the local

//machine

NetServices.setDefaultGatewayUrl("http://localhost/mx/gateway&quot;);

//Invoke
the createGatewayConnection to initialize the Flash Remoting
//functionality
gatewayConnnection =
NetServices.createGatewayConnection();

//Bind the Java Object:
com.tallan.data.providers.FlashDemo
//to a service called
tallanDataService.
tallanDataService =
gatewayConnnection.getService
("com.tallan.data.providers.FlashDemo",
this);

//Invoke a method called getReportData on the service named

//tallanDataSerevice

tallanDataService.getReportData();

如上例子说明了连接到J2EE
Server和调用一个方法的过程。
为了处理实际的工作,必须在Flash客户端和J2EE
Server上的企业资源之间相互传递参数。所有的远端调用都在异步方法中调用。为了支持从服务器上返回值,必须在Flash客户端添加回调函数。只要网关从J2EE服务器上的函数返回值该回调函数就被调用。为了支持函数回调,ActionScript函数的函数名必须与被调用的Java方法名一致。在如下的例子中,方法是getReportData(),
因此ActionScript回调函数应当命名为getReportData_result;
function
getReportData_Result(result)
{
//Print the results from the app
server to the
//debug window

trace(result);
}
所有的方法调用信息,包括参数和返回值,都在客户端和服务器端以Action Message
Format(AMF)的格式传递。AMF是二进制信息格式,通过HTTP以一种类似于SOAP(Simple Object Access
Protocol)的方式传送。在网络中,AMF信息比SOAP信息要小得多,因而允许函数以更快的速度被调用。Flash
Remoting透明地处理Java对象和ActionScript对象之间的所有映射。

使得Flash成为J2EE前端的一个重要的特性是它的内嵌的XML解析功能。Flash生来就能够在全部在客户机上处理XML解析和DOM(Document
Object
Model)传递。如下的ActionScript代码解析一篇应用于2D图形中的包含x和y坐标的XML文档:
<graph>
<point>
<xvalue>10</xvalue>
<yvalue>5</yvalue>

<point>

<point>
<xvalue>20</xvalue>
<yvalue>10</yvalue>

<point>
</graph>
应用服务器上的一个产生图形文件文档的类:
public
class FlashDemo
{
public FlashDemo()

{
}
public Document
getReportData()
{
Document doc =null;

try
{
System.out.println("calling
getReportData");
DocumentBuilder builder =

DocumentBuilderFactory.newInstance().newDocumentBuilder();
doc=
builder.newDocument();

//Create a record as the
root element
Element element =
doc.createElement("graph");
Element
child1=doc.createElement("point");
child1.setAttribute("xvalue",
"February");
child1.setAttribute("yvalue",
"20");
element.insertBefore(child1,
null);
doc.appendChild(element);
这个简单的类将返回一个文档对象给Flash客户端解析;
下面的例子完成解析:
//Parse the XML document returned by the
server,
//keeping the results in an array called nodes
function
parseXML()
{
//Create a new array called nodes
nodes
= new Array();

//Initialize the nodes array to

//contain all of the children of the reportXML document
nodes =
reportXML.nodes;

// childCounter is used as a counter for the
child Nodes
childCounter = 0;

//childNodes will contain
the children of each node
childNodes = new Array();

//XAxisValue will contain the x-axis value to plot
xAxisValue = new
Array();

//YAxisValue will contain the y-axis value of the data
sets
yAxisValue = new Array();

//Iterate through the
first level children of the XML Doc
for (j=0; j<=nodes.length; j++)

{
//Check if the node Name is report i.e., the data
set
//belongs to graph
if (nodes[j].nodeName ==
"graph")
{
//Get the background color of the
graph
bgcolor =
"#000000";//snodes[j].attributes.bgcolor;
//Get the caption of
the graph
caption = nodes[j].attributes.caption;

//Get the x-axis name
xaxisname =
nodes[j].attributes.xaxisname;
//Get the y-axis
name
yaxisname = nodes[j].attributes.yaxisname;

//Get the min value of the y-axis
yaxisminvalue =
nodes[j].attributes.yaxisminvalue;
//Get the max value of the
y-axis
yaxismaxvalue =
nodes[j].attributes.yaxismaxvalue;
//Now, we get the
childNodes
childNodes = nodes[j].nodes;

//Iterate through all of the child nodes, pulling out
//their
x,y values and storing them in arrays

for (k=0;
k<=childNodes.length; k++)
{
//If the
node name is Set i.e., a graph data set, then we
retrieve
//and collect the values
if
(childNodes[k].nodeName == "point")
{

//Increment counter
childCounter=
childCounter+1;
//Get the x-axis
name
xAxisValue[childCounter] =
childNodes[k].attributes.xvalue;
//Get the
value
yAxisValue[childCounter] =
childNodes[k].attributes.yvalue;
}

}
}

}
}
上面的例子简单地解析了XML文档并将它存储在各数组中共以后的应用使用。
世界上有很多Flash开发者。因而Macromedia的网站上有很多免费的ActionScript库可用。有几个库可用来以图形格式绘制数据数组。通过使用这种方法,可以创建一个简单的应用来绘制应用服务器产生的XML文档,如下图所示:
image

由于Flash在处理丰富的媒体方面的优越性,你可以很容易地在上面的代码的基础上进行扩充,构想出一个更全面的图形应用。这个图形应用程序可以调用服务器上的方法来产生包含几个x-y坐标对的XML文档。将这些数据与一些可以自由使用的图形库结合在一起,Flash接口可以以一种令人愉快地方式为用户在图形上绘制出这些坐标。这个图形应用与基于HTML的图形应用是不同的,因为Flash应用程序只须一次以XML格式得到数据,不用对服务器进行其它的调用,它允许用户放大,钻取,
或者作用于未来的数据集。可以证明,这种方法在想要限制对服务器上CPU的占用率时是非常有用的。随着桌面电脑性能的变得越来越强大,应用程序将服务器端的负载分配给客户端的能力将愈发有用。Flash允许开发者将所有的XML解析和图形操作的工作交给客户端来做,从而将服务器解放出来处理其它的请求,以此来达到上述目的。

将Flash整合进你的J2EE应用
尽管对于J2EE开发者而言前端配置有多种选择,但不同的选择效果是不一样的。HTML和DHTML解决方案适合于处理文档驱动或简单的应用。而Swign/applet方案重量级应用中,配置环境已经安装了JVM的情况下有一定优势。然而,对于有些应用,Flash可能对客户端环境极有意义。Flash在含有少量脚本的多媒体应用中有优势。利用远端工具,开发者现在可以将Flash客户端整合进已有的J2EE体系结构中。

[本贴已被 yaojh302 于 2003-12-3
18:01:40 修改过]

使用Flash Remoting建立一个Hello World 应用

使用Flash Remoting建立一个Hello World 应用

你建立一个使用Flash Remoting ActionScript API连接远程服务的简单的Flash应用程序。你可以选择四种不同的远程服务,包括ColdFusion页,一个JavaBean,一个ASPX页,和一个WEB服务。Flash 应用请求最小调用不同远程服务的改变。

Building the remote service

建立远程服务

Flash Remoting 支持Java, ASP.NET,和基于ColdFusion 的远程服务。对于一个简单的Hello World 应用,下面表格列出平台的应用服务代码,和列出将文件放置到什么位置使Flash Remoting 可用。

Application server

应用服务器

Application server code

应用服务代码

File location

文件位置

ColdFusion MX

<cfset flash.result = "Hello from ColdFusion MX!">

Save the ColdFusion page as helloWorld.cfm in a folder named remoteservices under your web root.

保存命名为helloWorld.cfmColdFusion文件在你的WEB根目录下面。

JRun 4

package com.remoteservices;

import java.io.Serializable;

public class FlashJavaBean

implements Serializable {

private String message;

public FlashJavaBean() {

message = "Hello from Java!";

}

public String helloWorldJava() {

return message;

}

}

Save the compiled JavaBean class file to classes/com/remoteservices folder under the SERVER-INF directory.

保存编译的JavaBean class 文件到SERVER-INF 目录的classes/com/remoteservices

ASP.NET

<%@ Register TagPrefix="Macromedia" Namespace="FlashGateway" Assembly="flashgateway" %>

<%@ Page language="c#" debug="true" %>

<Macromedia:Flash ID="Flash" runat="server">

Hello from .NET!

</Macromedia:Flash>

Save the ASPX page as helloWorldNET.aspx in the flashremoting directory under your web root.

保存命名为helloWorldNET.aspx ASPX 页面在你WEB 根目录中。

从使用Flash Remoting ActionScriptFLASH中调用远程服务

建立一个使用Flash Remoting Flash应用实例,写ActionScriptFlash开发环境中,使七能够同远程服务连接以及调用服务功能。

To build a Flash application that calls remote services using Flash Remoting:

建立使用Flash Remoting调用远程服务的Flash 应用:

1.在Flash开发环境中,创建一个新的Flash文件,将其保存为serviceTest.fla.

2.拖拽RemotingClasses 库浮动在舞台上。

3.在文档窗口,插入一个文本域。

4.在属性面板里面突出文本域,命名文本域为messageDisplay 在菜单中选择动态文本

5.打开动作面板,插入下面的代码,替换斜体字形式的值,这些值你用于同服务器通信。下面的代码:

import mx.remoting.Service;

import mx.services.Log;

import mx.rpc.RelayResponder;

import mx.rpc.FaultEvent;

import mx.rpc.ResultEvent;

import mx.remoting.PendingCall;

import mx.remoting.RecordSet;

// 连接服务并创建服务对象

var howdyService:Service = new Service(

"gatewayUrl",

new Log(),

"serviceName",

null,

null );

// 调用服务 helloWorld() 方法

var pc:PendingCall = howdyService.serviceFunctionName();

// 告诉服务处理结果和失败信息

pc.responder = new RelayResponder( this, "serviceFunctionName_Result",

"serviceFunctionName_Fault" );

function serviceFunctionName_Result(result:ResultEvent)

{

// 显示成功结果

messageDisplay.text = result.result;

}

function serviceFunctionName_Fault(fault:FaultEvent)

{

//显示从服务端反馈的错误信息

messageDisplay.text = fault.fault.faultstring;

}

The ActionScript code creates a new Service object, howdyService, to create both the gateway connection and a reference to the remote service. You specify the following variables:

ActionScript 代码创建一个新的Service 对象,owdyService,同时创建连接网关和一个远程服务条目。你指定下面值:

gatewayUrl, 代表运行 Flash Remoting的本地应用服务器.例如,下面连接到ColdFusion服务的gatewayUrl:

http://localhost:8500/flashservices/gateway. 指定一个符合 你远程服务的gatewayUrl 值。

日志对象,被发送的调试信息

serviceName, 远程服务名. 选择对于这个例子合适的值, 参看下面的部分.

两个null代表connection(连接) 和responder(应答)参数。

serviceFunctionName 你调用的服务功能名. 选择适合这个例子值, 参看这部分列表.

呼叫howdyService.serviceFunctionName() 服务功能返回一个 PendingCall 对象, 在这个例子中被呼叫的电脑 .功能包含一个实例设定RelayResponder对象的回应属性. RelayResponder 对象包含被服务功能反馈的指定对象(第一个参数)方法.RelayResponder 构造中的第二个参数指定result处理方法,第三个参数指定fault 处理方法.

例子操作结果被命名为serviceFunctionName_Result()或者serviceFunctionName_Fault()的服务功能使用callback functions反馈. 如果调用服务功能成功, _Result 功能被呼叫 ,它也处理结果. 如果服务功能失败, _Fault被呼叫触发错误事件.

你期待从服务反馈回来的result, ResultEvent object中被返回.服务中返回的错误情况fault, 被在一个FaultEvent 对象中返回.

保存文件。

在前面的 ActionScript 代码中, 替换serviceName serviceFunctionName 值为下列表中的值, 同你的远程服务一致:

Remote service

远程服务

serviceName variable

serviceName

serviceFunctionName variable

serviceFunctionName

ColdFusion MX

remoteservices

helloWorld

JRun 4

com.remoteservices

helloWorldJava

ASP.NET

remoteservices

helloWorldNET

Web service

http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

getQuote