文章目录
第 10 章 JSP 访问 JavaBean
10.1 JavaBean 简介
JavaBean 是一种可重复使用、且跨平台的软件组件。可分为两种:一种是有用户界面(URI,User Interface)的 JavaBean。一种是没有用户界面,主要负责表示业务数据或者处理事务(如数据运算、操作数据库)的。JSP 通常访问的时后一种的 JavaBean。
JSP 和 JavaBean 搭配使用有三个好处:
- 使得 HTML 页面与 java 程序分离,这样便于维护代码。如果把所欲偶的程序代码都写到 JSP 网页中,会使得代码繁杂,难以维护。
- 可以降低 JSP 开发人员对 Java 编程能力的要求。
- JSP 侧重于生成动态网页,事务处理由 JavaBean 来完成,这样可以充分利用 JavaBean 组件的一个重要特性,提高开发网站的效率。
一个标准的 JavaBean 由以下几个特性:
- JavaBean 是一个公共的类。
- JavaBean 有一个不带参数的构造方法。
- JavaBean 通过 set 方法设置属性,get 方法获取属性。
- JavaBean 属性名与方法之间存现固定的对应关系,如 xyz, getXyz(),setXyz()。
- 如果希望 JavaBean 被持久化,那么可以使它实现 Serializable 接口。
提示:
JavaBean 中除了可以定义 get 和 set 方法,还可以像其他 java 类一样定义一些完成其他特定功能的方法。
10.2 JSP 访问 JavaBean 的语法
1、导入 JavaBean 类
<%@ page import="mypack.CounterBean" %>
2、声明 JavaBean 对象
<jsp:useBean>
标签用来声明 JavaBean 对象,如:
<jsp:useBean id="myBean" class="mypack.CounterBean" scope="session"/>
- id:代表 JavaBean 对象的 ID,实际上表示引用吧 JavaBean 对象的局部变量。以及存放在特定范围内的属性名。JSP 规范要求存放在所有范围内的每个 JavaBean 对象都有唯一的 ID。例如不允许在会话范围内存在两个 ID 为 “myBean”的JavaBean,也不允许在会话范围内和请求范围内分别存在 ID 为 “myBean” 的 JavaBean。
- class:用来指定 JavaBean 的类名。
- scope:JavaBean对象 的存放范围。可选值:page(页面范围)、request、session 和 application。
<jsp:useBean>
的处理流程如下:
- 定义一个名为 myBean 的局部变量。
- 尝试从 scope 指定的会话范围中读取名为 “myBean” 的属性,并使得 myBean 局部变量应用具体的属性。
- 如果在 scope 指定的会话范围内不存在,那么久通过默认的构造方法创建一个,并把它存放在指定的范围内。
<jsp:useBean>
与以下 Java 程序片段是等价的:
CounterBean myBean = null // 定义局部变量
myBean = (Counter)session.getAttribute("myBean");
if (myBean == null) {
myBean = new com.mypack.CounterBean();
session.setAttribute("myBean", myBean);
}
3、访问 JavaBean 的属性
如果要将 JavaBean 的某个属性输出到网页上,可以用 <jsp:getProperty>
标签,如:
<jsp:getProperty name="myBean" property="count" />
<jsp:getProperty>
标签根据 name 属性的值 “myBean” 找到由<jsp:useBean>
标签声明的 ID 为 “myBean” 的Counter 的对象,然后打印它的 count 属性。等价于一下 Java 代码:
<%=myBean.getCount()%>
Servlet 容器运行 <jsp:getProperty>
标签时,会根据 property 指定的属性名,自动调用 JavaBean 的响应的 get 方法。如果不存在对应的 get 方法,会抛出异常。
给 JavaBean 的某个属性赋值:
<jsp:setProperty name="myBean" property="count" value="1"/>
10.3 JavaBean 的范围
在<jsp:useBean>
标签中用 scope 属性设置。scope 的可选值有4个:
- page: 表示页面范围,是 scope 的默认值。
- request: 请求范围。
- session: 会话范围。
- application: web 应用范围。
10.3.1 JavaBean 在页面(page)范围内
页面范围对应的时间段为:从客户请求访问一个 JSP 文件开始,到这个 JSP 文件执行结束。
在 pageCounter1.jsp 页面 中声明了一个存放在页面范围内的 CounterBean:
<jsp:useBean name="myBean" scope="page" class="com.mypack.CounterBean" />
每次当请求访问该页面时,<jsp:useBean>
标签都会创建一个 CounterBean 对象,把它存放在这个页面范围内。这个 CounterBean 对象在一下两种情况下结束生命周期:
- 客户请求的当前页面执行完毕,然后通过
<jsp:forward>
标记将请求转发到另一个 Web 组件。 - 客户请求的当前页面执行完毕,并向客户端发回响应。
<%@ page import="mypack.CounterBean" %>
<html>
<head><title>Counter</title></head>
<body>
<jsp:useBean id="myPageBean" scope="page" class="mypack.CounterBean" />
<%-- 把myPageBean的count属性的值加1 --%>
<jsp:setProperty name="myPageBean" property="count"
value="<%=myPageBean.getCount()+1 %>" />
<%-- 打印myPageBean的count属性 --%>
Current count value is :<jsp:getProperty name="myPageBean" property="count" />
<%
String scopeNames[]={"No scope","page","request","session","application"};
//寻找myPageBean的范围
int scope=pageContext.getAttributesScope("myPageBean");
%>
<%--打印myPageBean的范围 --%>
<p>scope=<%=scopeNames[scope]%></p>
<%--把请求转发给pageCounter2.jsp --%>
<%-- <jsp:forward page="pageCounter2.jsp" /> --%>
</body>
</html>
(1)通过客户端访问结果如下:
Current count vlaue is : 1
scope=page
(2)浏览器多次访问,看到的结果是一样的,count 的值始终为一。说明
<jsp:setProperty name="myPageBean" property="count"
value="<%=myPageBean.getCount()+1 %>" />
每一次都是重新给 count 赋值。
(3)将转发到 pageCounter2.jsp 的注释取消掉,
pageCounter2.jsp
<%@ page import="mypack.CounterBean" %>
<html><head><title>Counter</title></head>
<body>
<jsp:useBean id="myPageBean" scope="page" class="mypack.CounterBean" />
Current count value is :<jsp:getProperty name="myPageBean" property="count" />
</body>
</html>
pageCounter2.jsp 同样声明了一个 “myPageBean” 的 CounterBean 对象。
(4)访问 pageCounter1.jsp,会被请求转给 pageCounter2.jsp。结果如下
current count vlaue is :0
所以 pageCounter1.jsp 和 2.jsp 的页面范围是独立的。当请求被转发到 pageCounter2.jsp 的时候,1中的CounterBean对象的生命周期就结束了。
10.3.2 JavaBean 在请求(request)范围内
请求范围: 从客户请求访问一个 JSP 文件开始到返回响应结果结束,如果这个 JSP 文件把请求转发给其他 Web 组件了,那么直到其他 Web 组件返回响应结果结束。
对于请求范围内的 JavaBean 对象,生命周期会在以下两种情况结束;
- 请求执行完毕向客户端返回响应结果。
- 请求转发后由其他组件返回响应结果。
即请求范围内的 JavaBean 对象存在于响应一个客户请求的整个过程中。当所有共享一个请求的 JSP 文件执行完毕并向客户端响应时,本次请求范围内的 JavaBean 对象结束生命周期。
请求范围内的 JavaBean 对象实际上是作为属性保存在 HttpServletRequest 对象中的,属性名为 JavaBean 的ID。属性值为 JavaBean 对象。因此可以通过 HttpServletRequest.getAttribute() 方法读取请求范围内的 JavaBean 对象。如:
CounterBean obj = (CounterBean)request.getAttribute("myRequestBean");
或者直接通过<jsp:getProperty>
标签获取。
<jsp:getProperty name=“myRequestBean” property=“count” />
JavaBean 在会话(session)范围内
会话范围对应整个会话的生命周期。处于同一个会话中的 Web 组件共享这个会话范围内的 JavBean 对象。
会话范围内的 JavaBean 对象是保存在 HttpSession 对象中的。
session.getAttribute("mySessionBean");
JavaBean 在 Web 应用(application)范围内
对应整个 Web 应用的生命周期。处于同一个 Web 应用中的 Web 组件共享这个 Web 应用范围内的 JavaBean 对象。
保存在 ServletContext 对象中。
application.getAttribute();