加载头像

第五章 JSP 与 JavaBean

按照 Sun 公司的定义,JavaBean 是一个可重复使用的软件组件。实际上 JavaBean 是一种 Java 类,通过封装属性和方法成为具有某种功能或者处理某个业务的对象,简称 bean。

由于 JavaBean 是基于 Java 语言的,因此 JavaBean 不依赖平台,具有以下特点:

  • 可以实现代码的重复利用。
  • 易编写、易维护、易使用。
  • 可以在任何安装了 Java 运行环境的平台上的使用,不需要重新编译。

JSP 页面可以将数据的处理过程指派给一个或几个 bean 来完成,即 JSP 页面调用这些 bean 完成数据的处理,并将有关处理结果存放到 bean 中,然后 JSP 页面负责显示 bean 中的数据。使用 Java 程序片或某些 JSP 指令标记显示 bean 中的数据,即 JSP 页面的主要工作是显示数据,不负责数据的逻辑业务处理。

5.1 编写和使用 JavaBean

编写 JavaBean

编写 JavaBean 就是编写一个 Java 的类,所以只要会写类就能编写一个 JavaBean。这个类创建的一个对象称为一个 JavaBean ,简称 bean ,分配给 bean 的变量(成员变量),也称 bean 的属性。为了能让使用 bean 的应用程序构建工具(比如 Tomcat 服务器)使用 JSP 动作标记知道 bean 的属性和方法,在类的命名上需要遵守以下规则:

  1. 如果类的成员变量(也称 bean 的属性)的名字是 xxx,那么为了获取或更改 bean 的属性的值,类中必须提供两个方法:
    .getXxx(),用来获取属性 xxx。
    .setXxx(),用来修改属性 xxx。
    也就是方法的名字用 get 或 set 为前缀,后缀是将属性(成员变量)名字的首字母大写的字符序列。
  2. 类中定义的方法的访问权限都必须是 public 的。
  3. 类中必须有一个构造方法是 public、无参数的。

下面我们编写一个创建 bean 的 Java 类,并说明在 JSP 中怎样使用这个类创建一个 bean。要求创建 bean 的类带有包名,即 Java 源文件须使用 package 语句给出包名,例如:

1
package example;

或者

1
package example.example1;

保存 bean 的字节码

为了使 JSP 页面使用 bean,Tomcat 服务器必须使用相应的字节码文件创建一个对象,即创建一个 bean。为了让 Tomcat 服务器能找到字节码文件,字节码文件必须保存在特定的目录中。即 \WEB-INF\classes 目录下,根据包名对应的路径,在 classes 目录下再建立相应的子目录。
将创建 bean 的字节码文件,复制到 \WEB-INF\classes 中。为了调试程序方便,可以直接按照 bean 的包名将 bean 的源文件保存在 \WEB-INF\classes 目录中,然后编译其中的 Java 文件。

创建与使用 bean

使用 bean

使用 JSP 动作标记 useBean 加载使用 bean,语法格式是:

1
<jsp:useBean id="bean 的名字" class="创建 bean 的类" scope="有效范围"/>

或者

1
2
<jsp:useBean id="bean 的名字" class="创建 bean 的类" scope="有效范围">
</jsp:useBean>

bean 的加载原理

当 JSP 页面使用 JSP 动作标记 useBean 加载一个 bean 时,Tomcat 服务器首先根据 JSP 动作标记 useBeanid 给出的 bean 名字以及 scope 给出的使用范围(bean 生命周期),在 Tomcat 服务器管理的 pageContent 内置对象中查找是否含有这样的 bean(对象)。如果这样的 bean(对象)存在,Tomcat 服务器就复制这个 bean(对象)给 JSP 页面,就是常说的 Tomcat 服务器分配这样的 bean 给 JSP 页面。如果在 pageContent 中没有查找到 JSP 动作标记要求的 bean,就根据 class 指定的类创建一个 bean,并将所创建的 bean 添加到 pageContent 中。通过 Tomcat 服务器创建 bean 的过程可以看出,首次创建一个新的 bean 需要用相应类的字节码文件创建对象,当某些 JSP 页面再需要同样的 bean 时,Tomcat 服务器直接将 pageContent 中已经有的 bean 分配给 JSP 页面,从而提高 JSP 页面 bean 的使用效率。

如果修改了字节码文件,必须重新启动 Tomcat 服务器才能使用新的字节码文件。

bean 的有效范围和生存周期

scope 的取值范围给出了 bean 的生命周期(存活时间),即 scope 取值决定了 Tomcat 服务器分配给用户的 bean 的有效范围和生命周期,因此需要理解 scope 取值的具体意义。下面就 JSP 动作标记 useBeanscope 取值的不同情况进行说明。

page bean

scope 取值为 page 的 bean 称为 page bean,page bean 的有效范围是用户访问的当前页面,存活时间直到当前页面执行完毕。Tomcat 服务器分配给每个 JSP 页面的 page bean 是互不相同的。也就是说,尽管每个 JSP 页面的 page bean 的功能相同,但它们占有不同的内存空间。page bean 的有效范围是当前页面,当页面执行完毕,Tomcat 服务器取消分配的 page bean,即释放 page bean 所占有的内存空间。需要注意的是,不同用户(浏览器)的 page bean 也是互不相同的。也就是说,当两个用户同时访问同一个 JSP 页面时,一个用户对自己 page bean 的属性的改变,不会影响到另一个用户。

session bean

scope 取值为 session 的 bean 称为 session bean,session bean 的有效范围是用户访问的 Web 服务目录下的各个页面,存活时间是用户的会话期(session)间,直到用户的会话消失(session 对象达到了最大生存时间或用户关闭自己的浏览器以及服务器关闭)。如果用户访问 Web 服务目录多个页面,那么每个页面 id 相同的 session bean 是同一个 bean(占有相同的内存空间)。因此,用户在某个页面更改了这个 session bean 的属性值,其他页面的这个 session bean 的属性值也将发生同样的变化。当用户的会话(session)消失,Tomcat 服务器取消所分配的 session bean,即释放 session bean 所占有的内存空间。需要注意的是,不同用户(浏览器)的 session bean 是互不相同的(占有不同的内存空间)。也就是说,当两个用户同时访问同一个 Web 服务目录,一个用户对自己 session bean 属性的改变,不会影响到另一个用户(一个用户在不同 Web 服务目录的 session bean 互不相同)。

注意:当使用 session bean 时,要保证用户端支持 Cookie。

request bean

scope 取值为 request 的 bean 称为 request bean,request bean 的有效范围是用户请求的当前页面,存活时间是从用户的请求产生到请求结束。Tomcat 服务器分配给每个 JSP 页面的 request bean 是互不相同的。Tomcat 服务器对请求作出响应之后,取消分配给这个 JSP 页面的 request bean。简单地说,request bean 只在当前页面有效,直到响应结束。request bean 存活时间略长于 page bean 的存活时间,原因是 Tomcat 服务器认为页面执行完毕后,响应才算结束。需要注意的是,不同用户的 request bean 的也是互不相同的。也就是说,当两个用户同时请求同一个 JSP 页面时,一个用户对自己 request bean 属性的改变,不会影响到另一个用户。

application bean

scope 取值为 application 的 bean 称为 application bean,application bean 的有效范围是当前 Web 服务目录下的各个页面,存活时间直到 Tomcat 服务器关闭。Tomcat 服务器为访问 Web 服务目录的所有用户分配一个共享的 bean,即不同用户的 application bean 也都是相同的一个。也就是说,任何一个用户对自己 application bean 属性的改变,都会影响到其他用户(不同 Web 服务目录的 application bean 互不相同)。

5.2 获取和修改 bean 的属性

使用 useBean 动作标记获得一个 bean 后,在 Java 程序片或表达式中 bean 就可以调用方法产生行为,这种情况下,不要求创建 bean 的类遵守 setXxxgetXxx 等规则。获取或修改 bean 的属性还可以使用 JSP 动作标记 getPropertysetProperty,这种情况下,要求创建 bean 的类遵守 setXxxgetXxx 等规则,当 JSP 页面使用 getPropertysetProperty 标记获取或修改属性 xxx 时,必须保证 bean 有相应的 getXxxsetXxx 方法,即对方法名字的命名有特殊的要求。

getProperty 动作标记

使用 getProperty 动作标记可以获得 bean 的属性值,并将这个值用串的形式发送给用户的浏览器。使用 getProperty 动作标记之前,必须使用 useBean 动作标记获得相应的 bean。

getProperty 动作标记的语法格式是:

1
<jsp:getProperty name="bean 的 id" property="bean 的属性"/>

或者

1
2
<jsp:getProperty name="bean 的 id" property="bean 的属性">
</jsp:getProperty>

其中,name 取值是 bean 的 id,用来指定要获取哪个 bean 的属性的值,property 取值是该 bean 的一个属性的名字。

setProperty 动作标记

使用 setProperty 动作标记可以设置 bean 的属性值,使用 setProperty 动作标记之前,必须使用 useBean 动作标记获得相应的 bean。

setProperty 动作标记可以通过两种方式设置 bean 属性值。

  1. 将 bean 属性值设置为一个表达式的值或字符序列。

    1
    2
    <jsp:setProperty name ="bean 的 id" property="bean 的属性" value ="<%=expression%>"/>
    <jsp:setProperty name ="bean 的 id" property="bean 的属性" value ="字符序列"/>

    value 给出的值的类型要和 bean 的属性的类型一致。

  2. 通过 HTTP 表单的参数值来设置 bean 的相应属性值。

    • 用 form 表单的所有参数值设置 bean 相对应属性值的使用格式如下:

      1
      <jsp:setProperty name="bean 的 id" property="*"/>

      setProperty 标记的上述用法中不具体指定 bean 属性值将对应 form 表单中哪个参数指定的值,系统会自动根据名字进行匹配对应,但要求 bean 属性的名字必须在 form 表单中有名称相同的参数名字相对应,Tomcat 服务器会自动将参数的字符串值转换为 bean 相对应的属性值。

    • 用 form 表单的某个参数的值设置 bean 的某个属性值的使用格式如下:

      1
      <jsp:setProperty name="bean 的名字" property="属性名" param="参数名"/>

      setProperty 标记的上述用法具体指定了 bean 属性值将对应表单中哪个参数名(param)指定的值,这种设置 bean 的属性值的方法,不要求 property 给出的 bean 属性的名字和 param 给出的参数名一致,即不要求 bean 属性的名字必须和表单中某个参数名字相同。

      当把字符序列设置为 beans 的属性值时,这个字符序列会自动被转化为 bean 的属性类型。

5.3 bean 的辅助类

在写一个创建 bean 的类时,除了需要用 import 语句引入 JDK 提供的类,可能还需要自己编写一些其他的类,只要将这样类的包名和 bean 类的包名一致即可。

习题 5

  1. 假设 Web 服务目录 mymoon 中的 JSP 页面要使用一个 bean,该 bean 的包名为 blue.sky。请说明,应当怎样保存 bean 的字节码文件。

    答:将创建 bean 的字节码文件保存在 \mymoon\WEB-INF\classes\blue\sky 中。

  2. 假设 Web 服务目录是 mymoon,star 是 mymoon 的一个子目录,JSP 页面 a.jsp 保存在 star 中,并准备使用一个 bean,该 bean 的包名为 tom.jiafei。下列哪个叙述是正确的?

    A. 创建 bean 的字节码文件保存在 \mymoon\WEB-INF\classes\tom\jiafei

    B. 创建 bean 的字节码文件保存在 \mymoon\star\WEB-INF\classes\tom\jiafei

    C. 创建 bean 的字节码文件保存在 \WEB-INF\star\classes\tom\jiafei

    D. 创建 bean 的字节码文件保存在 \mymoon\WEB-INF\classes\start\tom\jiafei

  3. tom.jiafei.Circle 是创建 bean 的类,下列哪个标记是正确创建 session bean 的标记?

    A. <jsp:useBean id=circle class=tom.jiafei.Circle scope=page/>

    B. <jsp:useBean id=circle class=tom.jiafei.Circle scope=request/>

    C. <jsp:useBean id=circle class=tom.jiafei.Circle scope =session/>

    D. <jsp:useBean id=circle type=tom.jiafei.Circle scope =session/>

  4. 假设创建 bean 的类有一个 int 型的属性 number,下列哪个方法是设置该属性值的正确方法?

    A.

    1
    2
    3
    public void setNumber(int n) {
    number = n;
    }

    B.

    1
    2
    3
    void setNumber(int n) {
    number = n;
    }

    C.

    1
    2
    3
    public void SetNumber(int n) {
    number = n;
    }

    D.

    1
    2
    3
    public void Setnumber(int n) {
    number = n;
    }
  5. 假设 JSP 页面使用标记

    1
    <jsp:useBean id="moon" class="tom.jiafei.AAA" scope="page"/>

    创建了一个名字为 moon 的 bean,该 bean 有一个 String 类型、名字为 number 的属性。如果创建 moon 的 Java 类 AAA 没有提供 public String getNumber() 方法,JSP 页面是否允许使用如下 getProperty 标记获取 moon 的 number 属性值?

    1
    <jsp:getProperty name="moon" property="number"/>

    答:允许。


返回目录 上一章 下一章
博客快捷键
shift K
关闭快捷键功能
shift A
打开/关闭中控台
shift M
播放/暂停音乐
shift D
深色/浅色显示模式
shift S
站内搜索
shift R
随机访问
shift H
返回首页
shift L
友链页面
shift P
关于本站
shift I
原版/本站右键菜单
引用到评论
随便逛逛博客分类文章标签
复制地址关闭热评深色模式轉為繁體