第 1 章 JavaBeans 组件技术
类 EventExam 类使用 Vector 数据类型来存储事件监听者队列 EventExam 类定义了 addModelChangedListener()方法用来往事件监听者队列中添加事件监听者对象(表面上添加 的是事件监听者接口 ModelChangedListener 对象 但在实际上添加的是事件监听者对象 ModelChangedEventObject) removeModelChangedListener()方法可以把事件监听者队列中的 特定的事件监听者对象注销 事件源对象调用notifyModelChanged()方法通知事件监听者发 生了modelChanged 事件 notifyModelChanged()方法的方法体中 使用一个 for 循环结构 遍历 Vector 数据结构中保存的每一个事件监听者接口对象 调用它们的 modelChange()方 法 通知事件监听者 modelChanged 事件已经发生了 并且把事件状态对象 e 传递给这些 事件监听者 这里虽然调用的是ModelChangedListener 接口的 modelChange()方法 但是这 个方法并没有真正实现 所以实际上调用的是ModelChangedEventObject 类的 modelChange() 方法
事件适配器类
事件适配器类是 Java JavaBeans 事件模型中极其重要的一部分 在一些应用场合 事件从事件源到事件监听者之间的传递要通过事件适配器类来 转发 例如 当事件源发 出一个事件 而有几个事件监听者对象都可接收该事件 但只有指定的监听者对象可以做 出反应时 就要在事件源与事件监听者之间插入一个事件适配器类 由适配器类来指定事 件应该是由哪些事件监听者来响应 再由它来转发事件
注意 JavaBeans 的事件模型实际上用的并不多 尤其是应用于 JSP 程序中的 JavaBeans 很少需要响应或者监听某种事件的产生 但是这并不等于这部分的内容不重要 有时候为了纪录JavaBeans 都作了哪些敏感的操作 还是需要利用 JavaBeans 的 事件模型的
1.2 JSP 中如何使用 JavaBeans
JavaBeans 被称为是 Java 组件技术的核心 JavaBeans的结构必须满足一定的命名约 定 JavaBeans 类似于 Windows 下的 ActiveX 控件 它们都能提供常用功能并且可以重复 使用 JavaBeans 可以在 JSP 程序中应用给我们带来了很大的方便 这使得开发人员可 以把某些关键功能和核心算法提取出来 封装成为一个组件对象 增加了代码的重用 率 系统的安全性 比如 我们可以将访问数据库的功能 数据处理功能编写封装为 JavaBeans 组件 然后在某个 JSP 程序中加以调用 JavaBeans 技术与 ActiveX 相比 有 着很大的优越性 例如JavaBeans 的与平台无关性 使得 JavaBeans 组件不但可以运行 于Unix 平台 还可以运行在 Windows 平台下面 而且 JavaBeans 从一个平台移植到另 外的平台上代码不需要修改 甚至不需要重新编译 但是 ActiveX 就不同了 它只能 够应用于Windows 平台 而且它的代码移植性很差 从 Windows 98 平台移植到 NT 平 台就需要重新编译代码 甚至要大幅度改写程序 另一方面 JavaBeans 比 ActiveX 要 容易编写得多 用起来也方便得多 起码 JavaBeans 组件在使用以前不需要注册 而 ActiveX 控件在使用以前必须在操作系统中注册 否则在运行的时候 系统将会报错
本节将介绍在 JSP 程序中如何使用 JavaBeans 组件 要想在 JSP 程序中使用
第一部分 JSP 技术与 J2EE 技术
JavaBeans 组件 必须应用<jsp:useBean> <jsp:setProperty> <jsp:getProperty>等 JSP 的操 作指令 关于这几个操作指令的用法 我们在《JSP深入編程》中已经有所涉及 但是限于 体系结构方面的原因 我们的讨论十分肤浅 而且没有举出具体的例子 这不能不说是一 个缺憾 在这一节中 我们会结合实际的例子 再次详细介绍这三个操作指令的用法 顺 便帮助读者复习一下JSP 的基础知识
1.2.1 <jsp:useBean>操作指令
<jsp:useBean>操作指令用于在 JSP 页面中实例化一个 JavaBean 组件 这个实例化的 JavaBean 组件对象将可以在这个 JSP 程序的其它地方被调用 <jsp:useBean>操作指令的基 本语法形式如下所示
<jsp:useBean id="name" scope="page|request|session|application" typeSpec />
或者
<jsp:useBean id="name" scope="page|request|session|application" typeSpec />
body
</jsp:useBean>
语法参数描述
z id 属性用来设定 JavaBeans 的名称 利用 id 可以识别在同一个 JSP 程序中使用 的不同的JavaBeans 组件实例
z class 属性指定 JSP 引擎查找 JavaBeans 代码的路径 一般是这个 JavaBean 所对应 的Java 类名
z scope 属性用于指定 JavaBeans 实例对象的生命周期 亦即这个 JavaBean 的有效作 用范围 scope 的值可能是 page request session 以及 application 在下面 1.3 节 中 我们会详细讨论这四个属性值的含义与用法
typeSpec 可能是如下的四种形式之一 class="className"
或者
class="className" type="typeName"
或者
beanName="beanName" type=" typeName"
或者
type="typeName"
当 JavaBeans 组件对象被实例化以后 你就可以访问它的属性来定制它 我们要获得 它的属性值 应当使用<jsp:getProperty>操作指令或者是在 JSP 程序段中直接调用 JavaBeans 对象的getXXX()方法 <jsp:getProperty>操作指令的语法形式如下所示
<jsp:getProperty id="Name" property="name" />
使用这个操作指令可以获取将要用到的 JavaBeans 组件实例对象的属性值 实际的值 将会被放在输出语句中
要改变 JavaBeans 的属性 你必须使用<jsp:setProperty>操作指令或者是直接调用 JavaBeans 对象的方法 <jsp:setProperty>操作指令有以下两种语法形式
第 1 章 JavaBeans 组件技术
<jsp:setProperty id="Name" property="*" />
或者
<jsp:setProperty id="Name" property="propertyNumber" value="string" />
前者的功能是根据已提交的表单中的数据 设置这个JavaBean 中相应(JavaBeans 属性 的名称和表单对象的名称要相同)的属性值 后者的功能是把这个 JavaBeans 的指定的属性 设为指定的值
为了能在JSP 程序中使用 JavaBeans 组件 你需要特别注意 JavaBeans 类程序的存放问 题:为了使应用程序服务器能找到 JavaBeans 类 你需要将其类文件放在 Web 服务器的一个 特殊位置 以JSWDK1.0.1 服务器为例 JavaBeans 的类文件(编译好的 class 文件)应该放在 examples\WEB-INF\jsp\beans 目录下或者是 webpages\WEB-INF\jsp\beans 目录下面 在 resin 服务器中则是放在doc\WEB-INF\classes 目录下的 至于 JavaBeans 在其他服务器下的存放 路径 读者可以参考下文的介绍或者相应服务器的开发文档
1.2.2 <jsp:setProperty>操作指令
<jsp:setProperty>操作指令被用于指定 JavaBeans 的某个属性的值 它的语法形式如下 所示:
<jsp:setProperty name="BeanName" PropertyExpr />
PropertyExpr ::= property="*"|
property="PropertyName"|
property="PropertyName" value="PropertyValue"|
property="PropertyName" param="ParameterName"|
语法参数说明
z name name 属性用来指定 JavaBeans 的名称 这个 JavaBeans 必须首先使用
<jsp:useBean>操作指令来实例化
z property property 属性被用来指定 JavaBeans 需要定制的属性的名称 如果 property 属性的值为* 那么会发生什么情况呢?请参考 1.4.2 小节
z value value 属性的值将会被赋给 JavaBeans 的属性
z param param 这个属性的作用很微妙 如果客户端传递过来的参数中 有一个参 数的名字和param 属性的值相同 那么这个参数的值将会被赋给 JavaBean 的属性 所以使用了param 属性就不要使用 value 属性 反之 使用了 value 属性就不要使 用param 属性 这两个属性是互斥的 不过 param 属性必须和 property 属性搭配 使用 否则就不知道该赋值给JavaBeans 的哪一个属性了
我们不提倡读者使用<jsp:setProperty>操作指令 而应该在 JSP 程序段中直接调用 JavaBeans 组件实例对象的 setXXX()方法 因为后者的代码简单 使用起来比较灵活 相 对而言 前一种方法的代码就比较繁琐了 而且灵活性也不好 以param 属性为例 客户 端传递归来的参数值一般不应该直接赋给 JavaBeans 的属性 而应该先转换汉字的内码 再赋值 这一点上param 属性就无能为力了
第一部分 JSP 技术与 J2EE 技术
1.2.3 <jsp:getProperty>操作指令
<jsp:getProperty> 操 作 指 令 搭 配 <jsp:useBean> 操 作 指 令 一 起 使 用 可 以 获 取 某 个 JavaBean 组件对象的属性值 并使用输出方法将这个值输出到页面 <jsp:getProperty>操作 指令的语法形式如下所示
<jsp:getProperty name=”BeanName” Property=”PropertyName” />
语法参数说明
z name 这个属性用来指定 JavaBeans 的名称 这个 JavaBeans 组件对象必须已经使 用<jsp:useBean>操作指令实例化了
z Property Property 用来指定要读取的 JavaBeans 组件对象的属性的名称 实际上 我们也可以在JSP 程序段中直接调用 JavaBeans 对象的 getXXX()方法 来获 取JavaBeans 对象的属性值 我们觉得使用这个方法要比使用<jsp:getProperty>操作指令好 因为前者使用起来比较灵活 而且代码相对比较简单
1.2.4 JavaBeans 的开发流程
在这一小节里 我们将详细讨论如何开发JavaBeans 组件 如何把它用到 JSP 程序的 开发中去 实现一个完整的JavaBeans+JSP 的开发流程
编写JavaBeans 组件
第一步 应该是编写一个 JavaBeans 组件程序 我们这就根据上面介绍的知识 编写 一个十分简单的JavaBeans 程序 请看程序清单 1.8(HelloWorld.java)
程序清单 1.8
//File Name:HelloWorld.java //Author:fancy
//Date:2001.3.26
//Note:use this JavaBean to say hello world!
package test;
public class HelloWorld {
String Hello="hello world I am fancy!";
public void HelloWorld() {
}
public void setHello(String name) {
第 1 章 JavaBeans 组件技术
Hello=name;
}
public String getHello() {
return Hello;
} }
在 程 序 清 单 1.8(HelloWorld.java) 中 我 们 编 写 了 一 个 十 分 简 单 的 JavaBean HelloWorld 它有一个字符串类型的 Hello 属性 用于保存问候信息 在编写 HelloWorld.java 程序时 要注意HelloWorld 类必须显式声明为 public 类型 其次是 package 语句的使用 请看代码行:
package test;
这一行代码指示编译器把编译好的类作为test 包的一部分 HelloWorld.class(类文件) HelloWorld.java(程序文件)文件必须位于 test 文件夹中
编译HelloWorld.java 程序
编写好HelloWorld.java 程序以后 我们应该把它保存到哪里呢?以 JSWDK1.0.1 服务器 为例 应该把它保存到webpages\WEB-INF\jsp\beans\目录下面 我们必须新建一个文件夹 这个文件夹的名字必须和package 语句所指定的包名相同 否则服务器无法找到 JavaBean 的类代码 在本例中 这个文件夹的名字应该是 test 保存好 HelloWorld.java 程序后 使 用javac.exe 程序把它编译为 class 文件
编写JSP 程序
第三步是编写JSP 程序 调用我们在上面的步骤中编写好的 HelloWold 组件 请看程 序清单1.9(useBean.jsp)
程序清单 1.9
<%--
File Name:useBean.jsp Author:fancy
Date:2001.3.26
Note:use javabean to say hello world!
--%>
<jsp:useBean id="hello" scope="page" class="test.HelloWorld" />
<jsp:getProperty name="hello" property="Hello" />
<br>
<%
hello.setHello("Are you want to talk to me?");
%>
第一部分 JSP 技术与 J2EE 技术
<%=hello.getHello()%>
在程序清单1.9(useBean.jsp)中 首先使用<jsp:useBean>操作指令实例化了 HelloWorld 组件对象 在下面的代码中 就可以使用 hello 来引用 HelloWorld 组件对象 读者应该注
在程序清单1.9(useBean.jsp)中 首先使用<jsp:useBean>操作指令实例化了 HelloWorld 组件对象 在下面的代码中 就可以使用 hello 来引用 HelloWorld 组件对象 读者应该注