• 沒有找到結果。

5-1 属性( Attribute )与范围( Scope )

在文檔中 JSP 2.0技术手册 (頁 89-98)

有些 JSP 程序员会将 request、session、application 和 pageContext 归为一类,原因在于:

它们皆能借助 setAttribute( )和 getAttribute( )来设定和取得其属性(Attribute),通过这两种 方法来做到数据分享。

我们先来看下面这段小程序:

Page1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Page1.jsp</title>

</head>

<body>

</br>

<%

application.setAttribute("Name","mike");

application.setAttribute("Password","browser");

%>

<jsp:forward page="Page2.jsp"/>

</body>

</html>

在这个程序中,笔者设定两个属性:Name、Password,其值为:mike、browser。然后再转交(forward) 到 Page2.jsp。我只要在 Page2.jsp 当中加入 application.getAttribute( ),就能取得在 Page1.jsp 设定的数据。

Page2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - Page2.jsp</title>

</head>

<body>

<%

String Name = (String) application.getAttribute("Name");

String Password = (String) application.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

Page1.jsp 的执行结果如图 5-1 所示。

图 5-1 Page1.jsp 的执行结果

从图 5-1 可以看出,此时 Name 的值就会等于 mike,Password 的值就等于 browser。看完这个小 范例之后,读者有没有发现网页之间要传递数据时,除了可以使用窗体、隐藏字段来完成之外,JSP 技术还提供给开发人员一项传递数据的机制,那就是利用 setAttribute( )和 getAttribute( )方法,

如同 Page1.jsp 和 Page2.jsp 的做法。不过它还是有些限制的,这就留到下一节来说明。

在上面 Page1.jsp 和 Page2.jsp 的程序当中,是将数据存入到 application 对象之中。除了 application 之外,还有 request、pageContext 和 session,也都可以设定和取得属性值,那它们 之间有什么分别吗?

它们之间最大的差别在于范围(Scope)不一样,这个概念有点像 C、C++中的全局变量和局部变量 的概念。接下来就介绍 JSP 的范围。

5-1-1 JSP Scope—Page

JSP 有四种范围,分别为 Page、Request、Session、Application。所谓的 Page,指的是单单一 页 JSP Page 的范围。若要将数据存入 Page 范围时,可以用 pageContext 对象的 setAttribute( ) 方法;若要取得 Page 范围的数据时,可以使用 pageContext 对象的 getAttribute( )方法。我们将 之前的范例做小幅度的修改,将 application 改为 pageContext。

PageScope1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope1.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

<%

pageContext.setAttribute("Name","mike");

pageContext.setAttribute("Password","browser");

%>

<jsp:forward page="PageScope2.jsp"/>

</body>

</html>

PageScope2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope2.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

</br>

<%

String Name = (String)pageContext.getAttribute("Name");

String Password = (String)pageContext.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

执行结果如图 5-2 所示。

图 5-2 PageScope1.jsp 的执行结果

这个范例程序和之前有点类似,只是之前的程序是 application,现在改为 pageContext,但是结 果却大不相同,PageScope2.jsp 根本无法取得 PageScope1.jsp 设定的 Name 和 Password 值,因为在 PageScope1.jsp 当中,是把 Name 和 Password 的属性范围设为 Page,所以 Name 和 Password 的值只能 在 PageScope1.jsp 当中取得。若修改 PageScope1.jsp 的程序,重新命名为 PageScope3.jsp,如下:

PageScope3.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - PageScope3.jsp</title>

</head>

<body>

<h2>Page 范围 - pageContext</h2>

</br>

<%

pageContext.setAttribute("Name","mike");

pageContext.setAttribute("Password","browser");

String Name = (String)pageContext.getAttribute("Name");

String Password = (String)pageContext.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

PageScope3.jsp 的执行结果如图 5-3 所示。

图 5-3 PageScope3.jsp 的执行结果

经过修改后的程序,Name 和 Password 的值就能顺利显示出来。这个范例主要用来说明一个概 念:若数据设为 Page 范围时,数据只能在同一个 JSP 网页上取得,其他 JSP 网页却无法取得该数据。

5-1-2 JSP Scope—Request

接下来介绍第二种范围:Request。Request 的范围是指在一 JSP 网页发出请求到另一个 JSP 网 页之间,随后这个属性就失效。设定 Request 的范围时可利用 request 对象中的 setAttribute( ) 和 getAttribute( )。我们再来看下列这个范例:

RequestScope1.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - RequestScope1.jsp</title>

</head>

<body>

<h2>Request 范围 - request</h2>

<%

request.setAttribute("Name","mike");

request.setAttribute("Password","browser");

%>

<jsp:forward page="RequestScope2.jsp"/>

</body>

</html>

RequestScope2.jsp

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>CH5 - RequestScope2.jsp</title>

</head>

<body>

<h2>Request 范围 - request</h2>

<%

String Name = (String) request.getAttribute("Name");

String Password = (String) request.getAttribute("Password");

out.println("Name = "+Name);

out.println("Password = "+ Password);

%>

</body>

</html>

RequestScope1.jsp 的执行结果如图 5-4 所示。

现在将 Name 和 Password 的属性范围设为 Request,当 RequestScope1.jsp 转向到 RequestScope2.jsp 时, RequestScope2.jsp 也能取得 RequestScope1.jsp 设定的 Name 和 Password 值。不过其他的 JSP 网页

无法得到 Name 和 Password 值,除非它们也和 RequestScope1.jsp 有请求的关系。

图 5-4 RequestScope1.jsp 的执行结果

除了利用转向(forward)的方法可以存取 request 对象的数据之外,还能使用包含(include)的 方法。

假若我将 RequestScope1.jsp 的

<jsp:forward page="RequestScope2.jsp"/>

改为

<jsp:include page="RequestScope2.jsp" flush="true"/>

执行 RequestScope1.jsp 时,结果还是和图 5-4 一样。表示使用<jsp:include>标签所包含进来 的网页,同样也可以取得 Request 范围的数据。

5-1-3 JSP Scope—Session、Application

表 5-2 介绍了最后两种范围:Session、Application。

表 5-2

范 围 说 明

Session

Session 的作用范围为一段用户持续和服务器所连接的时间,但与服务 器断线后,这个属性就无效。只要将数据存入 session 对象,数据的范 围就为 Session

Application

Application 的作用范围在服务器一开始执行服务,到服务器关闭为 止。Application 的范围最大、停留的时间也最久,所以使用时要特别注 意,不然可能会造成服务器负载越来越重的情况。只要将数据存入 application 对象,数据的 Scope 就为 Application

表 5-3 列出了一般储存和取得属性的方法,以下 pageContext、request、session 和 application 皆可使用。

注意

pageContext 并无 getAttributeNames( )方法。

表 5-3

方 法 说 明

void setAttribute(String name, Object value) 设定 name 属性的值为 value Enumeration getAttributeNamesInScope(int

scope ) 取得所有 scope 范围的属性

Object getAttribute(String name) 取得 name 属性的值

void removeAttribute(String name) 移除 name 属性的值

当 我 们 使 用 getAttribute(String name) 取 得 name 属 性 的 值 时 , 它 会 回 传 一 个 java.lang.Object,因此,我们还必须根据 name 属性值的类型做转换类型(Casting)的工作。例如:

若要取得 String 类型的 Name 属性时:

String Name = (String)pageContext.getAttribute("Name");

若是 Integer 类型的 Year 属性时:

Integer Year = (Integer)session.getAttribute("Year");

到目前已大约介绍完 JSP 中四种范围(Scope):Page、Request、Session 和 Application。假若 我的数据要设为 Page 范围时,则只需要:

pageContext.setAttribute("Year", new Integer(2001));

若要为 Request、Session 或 Application 时,就分别存入 request、session 或 application 对象之中,如下:

request.setAttribute("Month", new Integer(12) );

session.setAttribute("Day", new Integer(27) );

application.setAttribute("Times", new Integer(10));

接下来就正式进入本章的主题:隐含对象(Implicit Object)。

在文檔中 JSP 2.0技术手册 (頁 89-98)