Java Server Pages 隐式对象


JSP隐式对象是Web容器加载的一组类的实例,它不像一般的Java对象那样用“new”去获取实例,而是可以直接在JSP页面使用的对象。JSP提供的隐式对象分为4个主要类别,列出了JSP提供的九个隐式对象及其分类。

与输入输出有关

request

javax.servlet.http.HttpServletRequest

请求端信息

response

javax.servlet.http.HttpServletResponse

响应端信息

out

javax.servlet.jsp.JspWriter

数据流的标准输出

与作用域通信有关

pageContext

javax.servlet.jsp.PageContext

表示此JSP的PageContext

session

javax.servlet.http.HttpSession

用户的会话状态

application

javax.servlet.ServletContext

作用范围比session大

与Servlet有关

config

javax.servlet.ServletConfig

表示此JSP的ServletConfig

page

java.lang.Object

如同Java的this

与错误有关

exception

java.lang.Throwable

异常处理

与输入输出有关的隐式对象

与输入输出有关的隐式对象是JSP页面非常常用的对象。输入和输出隐式对象有request、response和out。

request对象

request对象包含所有请求的信息,如:请求的来源、标头、cookies和请求相关的参数值等等。在JSP网页中,request对象是实现javax.servlet.http.HttpServletRequest接口的,HttpServletRequest接口所提供的方法,可以将它分为四大类:

取得请求参数的方法

存取和取得属性的方法

取得请求HTTP标头的方法

其他方法,如:取得请求的URL、IP和session等

方法

说明

String getParameter(String name)

取得name的参数值

Enumeration getParameterNames()

取得所有的参数名称

String[] getParameterValues(String name)

取得所有name的参数值

Map getParameterMap()

取得一个要求参数的Map

void setAttribute(String name, Object value)

以名称/值的方式,将一个对象的值存放到request中

Object getAttribute(String name)

根据名称去获取request中存放对象的值

response对象

response隐式对象处理JSP生成的响应,然后将响应发送个客户端。Response对象是实现javax.servlet.http.HttpServletResponse接口。其中常用的方法我们介绍如下三个,其它的方法如果需要请查看API帮助。

void setHeader(String name, String value);作用是设定标头。它还有两个类似的方法void setDateHeader()和void setIntHeader()。

通过这个函数,我们可以设定JSP页面的缓存方式,页面的自动更新,页面数据内容的有效性等等。

首先我们来看设定页面的缓存方式。如果是HTTP/1.0,我们通过如下方式设定

response.setHeader("Pragma", "no-cache");

如果是HTTP/1.1的情况,我们通过下边方式来设定。

response.setHeader("Cache-Control", "no-cache");

我们下面列举出HTTP/1.1的Cache-Control标头的设定参数,如下所示。

参数

说明

public

数据内容皆被存储起来,就连有密码保护的网页也是一样,因此安全性相当低

private

数据内容只能被存储到私有的caches,即non-shared caches中

no-cache

数据内容绝不被存储起来,dialing服务器和浏览器读到此标头,就不会讲数据内容存入caches中

no-store

数据内容除了不能被存入caches中之外,也不能存入暂时的磁盘中,这个标头防止敏感性数据被复制

must-revalidate

用户在每次读取数据时,会再次和原来的服务器确定是否为最新数据,而不再通过中间的代理服务器

proxy-revalidate

与must-revalidate有点像,不过中间接收的代理服务器可以互相分享caches

max-age=xxx

数据内容在经过xxx秒后,就会失效,这个标头就像Expires标头的功能一样,不过,max-age=xxx只能服务HTTP/1.1的用户。假设两者并用时,max-age=xxx有较高的优先权

通过上表最后一项max-age=xxx的介绍,我们知道还有一种方式设定在xxx秒后,数据内容失效的方法,我们举例如下,意思是数据内容在0秒后失效,即立即失效。

response.setDateHeader("Expires", 0);

如果我们想让网页自动更新,则要用到setIntHeader()方法和“Refresh”标头,使用方法如下:

response.setIntHeader("Refresh", 3);

当我们想在5秒后调用浏览器转到http://www.google.cn时,举例如下:

response.setHeader("Refresh", "5; URL=http://www.google.cn");

上述方法在HTML也有类似的方法实现,如下:

<meta http-equiv="Refresh" content="5;   URL=http://www.google.cn">

void setContentType(String name);作用是设置作为响应生成的内容的类型和字符编码。

void sendRedirect(String name);作用是发送一个响应给浏览器,指示其请求另一个URL。

下面,我们来举一个例子来说明上述方法。首先,创建response1.jsp,其中用到了上述方法,并重定向到response2.jsp。response1.jsp的代码如例6.1所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>直接跳转到response2.jsp</title>

</head>

<body>

<%

response.setContentType("text/html; charset=UTF-8");

response.sendRedirect("response2.jsp");

%>

</body>

</html>

下面我们来创建response2.jsp。我们在里边显示了response1.jsp中设定的ContentType,并设定每5秒画面自己刷新一次。代码如例6.2所示。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>自刷新</title>

</head>

<body>

response的content类型为:<%=response.getContentType()%>

<br>

<%

response.setIntHeader("Refresh", 5);

%>

</body>

</html>

例6.2

这时,我们看看执行结果,注意底下的刷新条,会不会每5秒刷新一次。如图6.1。

图6.1

现在我们修改response2.jsp页面的代码,设置5秒后迁移到Google的网站,代码如例6.3所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>自刷新</title>

</head>

<body>

response的content类型为:<%=response.getContentType()%>

<br>

<%

//   response.setIntHeader("Refresh", 5);

response.setHeader("Refresh", "5; URL=http://www.google.cn");

%>

</body>

</html>

例6.3

可以看到,5秒后自动跳转到了Google的网站上面。

6.2.3  out对象

out对象表示输出流,此输出流将作为请求的相应发送到客户端。我们前面已经多次用到了out对象。常用的方法有print()、println()和write()方法,这三个方法都用于向页面输出数据,下面我们通过out.jsp这个例子来说明一下out对象。代码如例6.4所示。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>out对象</title>

</head>

<body>

<%

// 获得out对象的默认缓冲区大小

int bufsize = out.getBufferSize();

// 获得经过程序执行,还剩下多少缓冲区

int remain = out.getRemaining();

// 计算用掉了多少缓冲区

int used = bufsize - remain;

// 用print方法输出默认缓冲区大小

out.print("默认缓冲区大小:" + bufsize + "<br>");

// 用println方法输出剩余缓冲区大小

out.println("剩余缓冲区大小:" + remain + "<br>");

// 用write方法输出已用缓冲区大小

out.write("已用缓冲区大小:" + used + "<br>");

%>

</body>

</html>

例6.4

在例子中,我们首先获得默认缓冲区大小,再获得剩余缓冲区大小,最后计算出已经使用的缓冲区大小,并显示出来。执行结果如图6.2所示。

图6.2

6.3  与Servlet有关的隐式对象

在JSP页面的执行过程中,每个JSP页面都会生成一个Servlet。Servlet对象提供的方法和变量以访问为JSP页面创建的Servlet的所有信息。它包含了page和config。

6.3.1  page对象

page对象代表JSP本身,更准确地说,它代表JSP被转译后的Servlet,因此,它可以调用Servlet类所定义的变量和方法。它是java.lang.Object类的一个实例。不过,page很少在JSP中使用,一般使用前面学过的page指令即可。例6.5的page.jsp为我们展示了如何通过page对象获得Servlet信息。执行结果如图6.3所示。

<%@ page info="这是page对象的例子" language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>page对象</title>

</head>

<body>

<%=((HttpJspPage) page).getServletInfo()%>

</body>

</html>

例6.5

图6.3

6.3.2  config对象

config对象存储Servlet的一些初始信息与page对象一样很少使用。config对象是javax.servlet.ServletConfig接口的一个实例。下面我们通过一个例子来演示通过config对象来获得web.xml中设定的Servlet初始参数值。首先在web.xml中配置Servlet。配置如图6.4,JSP页面config.jsp的代码如例6.6。

图6.4

注意:在3.6节,我们配置的是<servlet-class>标签,在这里,我们要设定的是<jsp-file>标签,指定了要执行的JSP页面。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>config对象</title>

</head>

<body>

<%

String val = config.getInitParameter("initparam");

out.println(val);

%>

</body>

</html>

例6.6

运行结果如图6.5所示。

图6.5

6.4  与错误有关的隐式对象

与错误有关的隐式对象只有一个就是exception对象。

JSP页面执行后,会在网页上显示内容。如果执行JSP过程中出现错误,JSP页面的执行就会终止。exception对象就是用于处理JSP页面中的错误。

在3.5.2节中,我们已经介绍了JSP错误的处理方式,使用的就是exception对象。在这里我们再举一个简单的例子,我们来写一个JSP来做除数为0的计算,并显示出错误信息。

我们先来创建div0.jsp,代码如例6.7所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8" errorPage="div0exception.jsp"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>除数为0的计算</title>

</head>

<body>

<%

int cnt = 5 / 0;

%>

</body>

</html>

例6.7

现在我们来创建异常处理页面div0exception.jsp,代码如例6.8所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8" isErrorPage="true"%>

<%@page import="java.io.PrintWriter"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>除数为0的计算错误处理</title>

</head>

<body>

除数为0错误:<%=exception%>

<br>

<%

exception.printStackTrace(new PrintWriter(out));

%>

</body>

</html>

例6.8

注意:作为错误处理对象的JSP必须设定page指令中的isErrorPage属性为“true”。而捕获错误的JSP必须设定page指令中的errorPage属性为处理错误的页面URL。而且,printStackTrace()函数的参数要为PrintWriter而不是JspWriter。

运行结果如图6.6所示。当我们迁移到div0.jsp时发生除数为0错误,直接跳转到处理错误的div0exception.jsp。

图6.6

6.5  与作用域通信有关的隐式对象

本节中,我们要介绍pageContext、session、application这三个对象。PageContext对象提供存取所有在此网页中可被利用的隐式对象,并且管理它们的属性;session对象提供一些机制,保存和跟踪用户的会话状态;application对象能够作用域整个应用程序,所有客户端窗口都可以共享该对象。

6.5.1  session对象

session对象表示用户的会话状况,用此项机制可以轻易识别每一个用户,能保存和跟踪用户的会话状态。例如,购物车最常使用session的概念,当用户把商品放入购物车,再去添加另外的商品到购物车时,原先选购的商品仍然在购物车内,而且用户不用反复去做身份验证。但如果用户关闭Web浏览器,则会终止会话。

session对象存储有关用户会话的所有信息。session对象用于在应用程序的网页之间跳转时,存储有关会话的信息。

session对象常用的方法如下:

方法

说明

long getCreationTime()

取得session产生的时间,单位是毫秒,由1970年1月1日零时算起

String   getId()

返回session的ID

long getLastAccessedTime()

返回用户最后通过这个session送出请求的时间,单位是毫秒,由1970年1月1日零时算起

long getMaxInactiveIntrval()

返回最大session不活动的时间,若超过这个时间按,session会失效,时间单位是秒

void invalidate()

取消session对象,并将对象存放的内容完全抛弃

boolean isNew()

判断session是否为“新”的,所谓“新”的session,表示session已由服务器产生,但是client尚未使用

void   setMaxInactiveInterval(int interval)

设定最大session不活动的时间,若超过这个时间,session将会失效,时间单位为秒

void   setAttribute(String name, Object value)

以名称/值的方式,将一个对象的值存放到session中

Object   getAttribute(String name)

根据名称去获取session中存放对象的值

下面我们就来举一个例子来看看这些方法。sessionfun.jsp代码如例6.9所示。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@page import="java.util.Date,java.text.SimpleDateFormat"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>session 使用</title>

</head>

<%!

// 格式化时间

public String fmt(Date date) {

SimpleDateFormat sdf =

new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

return sdf.format(date);

}

%>

<%

// 向session中设定key/value对,user/admin

session.setAttribute("user", "admin");

// 设定session最大不活动时间,我们设定为5秒

session.setMaxInactiveInterval(5);

%>

<body>

session生成时间:<%=fmt(new   Date(session.getCreationTime()))%>

<br>

session   ID:<%=session.getId()%>

<br>

最后发送请求时间:<%=fmt(new Date(session.getLastAccessedTime()))%>

<br>

最大session不活动时间:<%=session.getMaxInactiveInterval()%>

<br>

<a href="showsession.jsp">显示存放在session中的值</a>

</body>

</html>

例6.9

在例中,我们往session中存入key为user值为admin的数据对,然后设定session会在5秒没有任何操作的情况下失效。并显示session的ID,生成时间等等的内容。在最下边,有一个连接迁移到另一个页面showsession.jsp中显示session中user:admin的数据对。showsession.jsp代码如例6.10。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>显示存放在session中的值</title>

</head>

<body>

user:<%=session.getAttribute("user")%>

</body>

</html>

例6.10

执行结果如图6.7所示。

图6.7

此时,我们点击“显示存放在session中的值”链接,页面显示结果如图6.8。

图6.8

如果在如图6.7的页面中什么操作都不做等5秒以后,再点击“显示存放在session中的值”链接,将得到如图6.9的页面,得到的user值为null,因为session已经过期了。

图6.9

6.5.2  application对象

application对象实现javax.servlet.ServletContext接口,它主要功能在于取得或更改Servlet的设定。application对象的生命周期最长,它从服务器启动开始就存在,知道服务器关闭为止。

application对象的常用方法如下:

方法

说明

String   getServerInfo()

返回Servlet容器名称及版本号

URL getResource(String path)

返回指定资源(文件及目录)的URL路径

int getMajorVersion()

返回服务器支持的Servlet API最大版本号

int getMinorVersion()

返回服务器支持的Servlet API最小版本号

String getMimeType(String file)

返回指定文件的MIME类型

ServletContext getContext(String uri)

返回指定地址的Application context

String   getRealPath(String path)

返回本地端path的绝对路径

void log(String msg)

将信息写入log文件中

void log(String msg, Throwable err)

将stack trace所产生的异常信息写入log

void   setAttribute(String name,Object value)

以名称/值的方式,将一个对象的值存放到applicaton中

Object   getAttribute(String name)

根据名称去获取application中存放对象的值

void   removeAttribute(String name)

删除一个属性及其属性值

我们来举一个简单的例子来看看这些方法的使用。appfun.jsp的代码如例6.11所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>application 使用例</title>

</head>

<body>

首先执行setAttribute()方法,设置user:admin,

<%

// 向application里存放user:admin对

application.setAttribute("user", "admin");

%>

<br>

接着执行getAttribte("user")方法,<br>

设置user后:<%=application.getAttribute("user")%><br>

然后我们执行removeAttribute("user"),<br>

<%

// 删除user

application.removeAttribute("user");

%>

我们再次执行getAttribte("user")方法。<br>

删除user后:<%=application.getAttribute("user")%><br>

<br>

获得Srevlet容器版本:<%=application.getServerInfo()%>

<br>

Servlet容器最大版本:<%=application.getMajorVersion()%>

<br>

Servlet容器最小版本:<%=application.getMinorVersion()%>

<br>

</body>

</html>

例6.11

执行结果如图6.10所示。

图6.10

6.5.3  pageContext对象

pageContext对象使用户可以访问页面作用域中定义的隐式对象。pageContext对象也提供方法来访问隐式对象的所有属性,但必须制定范围的参数。它的作用范围仅仅在页面内。

pageContext对象用来获得其他隐式对象的函数如下:

函数

说明

Exception getException()

返回当前页面的异常,不过此页面的page指令中,isErrorPage属性必须为“true”,即exception对象

JspWriter getOut()

返回当前页面的输出流,即out对象

Object getPage()

返回当前页面的Servlet实体,即page对象

ServletRequest getRequest()

返回当前页面的请求,即request对象

ServletResponse getResponse()

返回当前页面的响应,即response对象

ServletConfig getServletConfig()

返回当前页面的ServletConfig对象,即config对象

ServletContext getServletContext()

返回当前页面的执行环境,即application对象

HttpSession getSession()

返回与当前页面关联的会话,即session对象

pageContext对象中与属性有关的函数如下:

函数

说明

void setAttribute(String name, Object attr)

page范围内设置属性和属性值

void setAttribute(String name, Object attr, int scope)

在制定范围内设定属性和属性值

Object getAttribute(String name)

page范围内根据名字获得属性值

Object getAttribute(String name, int scope)

在指定范围内获得属性值

void removeAttribute(String name)

page范围内删除属性

void removeAttribute(String name, int scope)

在制定范围内删除属性

Object findAttribute(String name)

所有范围中根据名字寻找属性

int getAttributeScope(String name)

返回某属性的作用范围

Enumeration getAttributeNamesInScope(int scope)

返回指定范围内可用的属性名枚举

在上边函数中,多次用到了范围,我们看看javax.servlet.jsp.PageContext类所提供的关于属性范围的常量,关于属性范围的详细介绍我们将在下一节进行。

常量

说明

PAGE_SCOPE

1

page范围

REQUEST_SCOPE

2

request范围

SESSION_SCOPE

3

session范围

APPLICATION_SCOPE

4

application范围

我们再来看看一些其他的函数。

函数

说明

void release()

释放pageContext所占用的资源

void forward(String relativeUrlPath)

使当前页面重定向到另一个页面

void include(String relativeUrlPath)

在当前位置包含另一文件

下面我们来举个例子pagecontext.jsp,首先向session中存入user:admin和password:123的属性,然后再通过getAttributeNamesInScope()方法来取到所有key,并把属性值同时表示出来。代码如例6.12。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<%@page import="java.util.Enumeration"%><html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>pageContext</title>

</head>

<body>

<%

// 设定属性

session.setAttribute("user", "admin");

session.setAttribute("password", "123");

// 定义变量

String key = null;

Object val = null;

%>

SESSION属性:<br>

<%

// 获得所有范围是SESSION的属性名

Enumeration em = pageContext

.getAttributeNamesInScope(PageContext.SESSION_SCOPE);

// 把SESSION范围的所有属性显示出来

while (em.hasMoreElements()) {

key = (String) em.nextElement();

val = pageContext.getAttribute(key, PageContext.SESSION_SCOPE);

out.println(key + " :" + val + "<br>");

}

%>

</body>

</html>

例6.12

执行结果如图6.11所示。

图6.11

6.6  属性和范围

以上5节我们把JSP的九大隐式对象都讲解完了,这一节我们来讲非常重要的一个概念,属性和范围。

很多程序员会将九大隐式对象中的pageContext、request、session和application四个对象归为一类,原因在于:它们都能借助setAttribute()方法和getAttribute()方法来设定和取得其属性,并通过这两种方法来做到数据共享。

我们来先看看下面这段小程序。attr1.jsp代码如例6.13所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>属性和范围attr1.jsp</title>

</head>

<body>

<%

// 设置属性

application.setAttribute("name", "admin");

application.setAttribute("password", "123");

%>

<!-- 迁移页面 -->

<a href="attr2.jsp">迁移到attr2.jsp</a>

</body>

</html>

例6.13

由上述代码可以知道,我们设定了两个属性:name和password,其值分别为:admin和123。然后再转交(forward)到attr2.jsp。我们只需要在attr2.jsp中调用application的getAttribute()方法,就可以取得在attr1.jsp中设定的数据。

我们再来看看attr2.jsp的代码,如例6.14。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>属性和范围attr2.jsp</title>

</head>

<body>

<%

// 获得属性值

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

String pwd = (String) application.getAttribute("password");

// 输出属性及其值

out.println("Name = " + name + " ; Password = " +   pwd);

%>

</body>

</html>

例6.14

我们来执行attr1.jsp,运行结果如图6.12所示。

图6.12

当我们点击“迁移到attr2.jsp”链接后,迁移到如图6.13的显示页面,从图中可以清楚地看到,此时Name为name的属性值admin,而Password为password的属性值123。也就是说,attr1.jsp中设置的属性被传递到了attr2.jsp中。

图6.13

通过上例我们会发现,网页之间要传递数据是,除了可以使用url后连接字符串,用表单,隐藏域(HTML的hidden)完成之外,JSP技术还提供给开发人员一项传递数据的机制,那就是利用setAttribute()方法和getAttribute()方法。

在上面的例子中,我们将数据存入到application对象之中,除了application对象,还有request、session和pageContext对象,也都可以设定和获取属性值,那它们之间有什么区别吗?那就是它们能作用到的范围不一样,和C、C++中的全局变量和局部变量的概念有些相似。接下来,我们就来介绍分别介绍pageContext、request、session和application的范围。

6.6.1  Page范围

JSP中有四种范围:Page、Request、Session和Application。所谓的Page,指的是只在一个JSP页面中起作用。若要将数据存入Page范围时,可以用pageContext对象的setAttribute()方法;若要取得Page范围的数据时,可以使用pageContext对象的getAttribute()方法。我们将上一节的例子做小幅度的修改,将application改为pageContext,并在attr1.jsp(例6.15)中显示刚刚设定的属性。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<title>属性和范围attr1.jsp</title>

</head>

<body>

<%

// 设置属性

//application.setAttribute("name",   "admin");

//application.setAttribute("password",   "123");

pageContext.setAttribute("name", "admin");

pageContext.setAttribute("password", "123");

%>

显示我们设定在pageContext中的属性:<br>

<%

// 获得属性值

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

String pwd =   (String) pageContext.getAttribute("password");

// 输出属性及其值

out.println("Name = " + name + " ; Password = " + pwd);

%>

<br>

<!-- 迁移页面 -->

<a href="attr2.jsp">迁移到attr2.jsp</a>

</body>

</html>

例6.15

我们再来创建上例中要迁移到得页面attri2.jsp,如例6.16所示

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<title>属性和范围attr2.jsp</title>

</head>

<body>

<%

// 获得属性值

//String name = (String)   application.getAttribute("name");

//String pwd = (String) application.getAttribute("password");

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

String pwd = (String)   pageContext.getAttribute("password");

// 输出属性及其值

out.println("Name = " + name + " ; Password = " +   pwd);

%>

</body>

</html>

例6.16

我们来执行attr1.jsp,运行结果如图6.14所示。

图6.14

如图所示,我们在本页面中获得了我们设定在pageContext中的属性,我们来点击链接“迁移到attr2.jsp”。执行结果如图6.15所示。

图6.15

在这个页面,我们已经不能获得name和password属性的值了,和我们上节的例子结果大不相同。

由此可知,我们把application改成了pageContext, 即把name和password属性设定为Page范围,这时,attr2.jsp根本无法取得attr1.jsp设定的属性,而只能在attr1.jsp本身来获得。即Page范围的属性只能在设定此属性的页面中被使用,其他页面是无法获得和使用这些属性的。

6.6.2  Request范围

接下来我们来看看第二种范围:Request。Request的范围是指在一个JSP网页发出请求道另一个JSP页面之间,随后,这个属性就失效了。设定Request范围的属性时可以利用request对象中的setAttribute()和getAttribute()方法。下面,我们来举例说明。

注意:下例的代码中使用到了<jsp:forward>和<jsp:include>标签,这是JSP标签,我们会在下一章讲到,这里只需要它的作用是迁移页面和导入文件就行了。

req1.jsp代码如例6.17所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Request范围_req1.jsp</title>

</head>

<body>

<%

// 设置属性

request.setAttribute("name", "admin");

request.setAttribute("password", "123");

%>

<!-- 迁移页面 -->

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

</body>

</html>

例6.17

req2.jsp代码如例6.18所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Request范围_req2.jsp</title>

</head>

<body>

<%

// 获得属性值

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

String pwd = (String)   request.getAttribute("password");

// 输出属性及其值

out.println("Name = " + name + " ; Password = " +   pwd);

%>

</body>

</html>

例6.18

我们同时创建一个req3.jsp,代码内容与req2.jsp相同,但是req1.jsp并没有请求req3.jsp这个页面。

执行req1.jsp可以看到如图6.16所示的结果。由此可知,req1.jsp设置了Request范围的属性,只有其请求的req2.jsp才能获得这些属性,而其他与req1.jsp没有请求关系的页面如req3.jsp则无法获得这些属性。如图6.17所示。

图6.16

图6.17

对于Request范围的属性的传递,也不是所有的方法都能够传递,对于上面的例子,我们使用了<jsp:forword>标签,我们现在把其换成<jsp:include>标签。

我们只是把例6.17中的如下的语句。

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

换成了

<jsp:include flush="false" page="req2.jsp"/>

执行结果如图6.18所示,同样能够获得request中的属性。

图6.18

对于Servlet使用Request范围属性,我们也举个例子来说明。

我们来创建Servlet类RequestServlet。代码如例6.19所示。

/*

* RequestServlet.java

* 2009-06-20

*

* 功能:Servlet使用Request范围属性

*/

package com.jy.sample.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import   javax.servlet.http.HttpServlet;

import   javax.servlet.http.HttpServletRequest;

import   javax.servlet.http.HttpServletResponse;

/**

* Servlet获得使用Request范围属性演示.

* @author JY

*/

public class RequestServlet extends   HttpServlet {

/** SerialVersionUID */

private static final long serialVersionUID =   6059392640873214193L;

/**

* 处理Get请求

* @param req Request

* @param resp Response

* @throws ServletException Servlet异常

* @throws IOException IO异常

*/

@Override

protected void doGet(HttpServletRequest req,   HttpServletResponse resp)

throws ServletException, IOException {

// 设置属性

req.setAttribute("name", "admin");

req.setAttribute("password", "123");

// 请求./req2.jsp

req.getRequestDispatcher(

"./req2.jsp").forward(req, resp);

}

}

例6.19

我们新建一个JSP页面req4.jsp,如例6.20所示,里边只有一个链接,来调用我们写的Servlet。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Servlet中使用Request范围的属性</title>

</head>

<body>

<a href="ReqServlet">Servlet中使用Request范围的属性</a>

</body>

</html>

例6.20

和以前Servlet的例子一样,我们要配置web.xml文件,如图6.19所示。

由于我们在Servlet中请求的req2.jsp没有任何变化,所以,我们不再列出其代码。

图6.19

我们执行req4.jsp,如图6.20所示。

图6.20

点击链接后,迁移到req2.jsp,我们看到,页面获得了属性。如图6.21。

图6.21

现在,我们来修改RequestServlet类的代码,将如下代码

// 请求./req2.jsp

req.getRequestDispatcher(

"./req2.jsp").forward(req, resp);

换成

// 重定向到./req2.jsp

resp.sendRedirect("./req2.jsp");

我们再次执行req4.jsp并且点击上边的链接。我们会得到如图6.22的结果,页面无法得到Request范围的属性。

图6.22

由上面可以知道,Servlet中的HttpServletRequest的getRequestDispatcher(请求的链接).forward()方法是会带着Request范围的属性进行传递,而HttpServletResponse的sendRedirect()方法是重定向,只是迁移到某个页面,而Request范围的属性会被丢弃而不跟随传递的。

我们来总结些什么情况能够获得请求中Request范围的属性,什么时候得不到。如下表。

方法

能否得到Request范围属性

<jsp:forward>

true

<jsp:include>

true

HttpServletRequest.getRequestDispatcher().forward()

true

HttpServletResponst.sendRedirect()

false

6.6.3  Session范围

Session作用范围比Page和Request范围要大,一般只有三种情况,Session范围的属性才会失效,第一种就是我们设定了session的最大不活动时间,我们在讲解session隐式对象的时候提到过,即在没有任何操作的情况下,多少秒后session对象失效;第二种是我们在web.xml中设置session过期时间,和第一种效果一样,即在没有任何操作的情况下,超过设定的时间,session对象会失效,和第一种不同的是单位是分钟;第三种就是关闭浏览器了,这就意味着我们和服务器断线,这样也会让session对象失效。我们设定Session范围同样就是设定session对象的setAttribute()和getAttribute()方法。

这里,我们举例说明Session范围。我们建立3个不同的JSP,其中sess1.jsp中只是设置session对象的属性,并有链接迁移到sess2.jsp。如例6.21所示,而其他两个页面sess2.jsp和sess3.jsp都只是获得并表示session对象中的属性,代码一样,如例6.22所示。而且sess1.jsp和另外两个显示的JSP之间没有请求关系。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<title>Session范围_sess1.jsp</title>

</head>

<body>

<%

// 设置属性

session.setAttribute("name", "admin");

session.setAttribute("password", "123");

%>

<a href="sess2.jsp">迁移到sess2.jsp</a>

</body>

</html>

例6.21

<%@ page language="java" contentType="text/html;   charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Session范围_sess2.jsp</title>

</head>

<body>

<%

// 获得属性值

String name = (String) session.getAttribute("name");

String pwd = (String)   session.getAttribute("password");

// 输出属性及其值

out.println("Name = " + name + " ; Password = " +   pwd);

%>

</body>

</html>

例6.22

我们首先运行sess1.jsp。如图6.23所示。

图6.23

点击链接后迁移到sess2.jsp,如图6.24所示。

图6.24

我们直接在地址栏输入sess3.jsp的地址,并回车,结果如图6.25。

图6.25

只要我们不关闭浏览器,都可以获得我们设置的name和password属性。当我们关闭浏览器后再打开浏览器并在地址栏输入sess2.jsp或sess3.jsp的地址,回车后,发现name和password属性的值取不到了。如图6.26所示。

图6.26

现在,我们来通过设置web.xml的<session-config>标签来设定session过期时间,如图6.27所示。其中只有<session-timeout>标签,设置的时间单位是分钟,其中设置为1就表示1分钟没有任何操作的话,session会过期。

图6.27

我们执行sess1.jsp后,不要对此页面有任何操作,1分钟后,我们点击链接会得到如图6.28所示的结果。

图6.28

至于在代码中设置最大不活动时间的例子我们已经在6.5.1节举过例子,在这里就不再举例了。当在设定的时间内没有任何操作,session对象就会失效,属性也就不能获得了。

注意:对于不同的服务器都会设定默认的最大不活动时间,因此,实际情况是,并非只要开着浏览器session就不会过期失效,而是根据各服务器设定时间的长短,失效时间各不相同,而我们在6.5.1节设定最大不活动时间和在web.xml中设置session失效时间,只是按照我们自己的要求来设定,我们的设定值会覆盖服务器默认的设定值而已。

对于session对象的使用,我们需要特别注意,通过setAttribute()方法设定属性后,在使用完此属性后,一定要通过removeAttribute()方法删除,否则,session内数据越来越多,占用的内存越来越大,服务器的负载就越来越大。

6.6.4  Application范围

Application的作用范围是从服务器一开始执行服务到服务器关闭为止。Application的范围最大,停留的时间也最长,所以要使用时同session一样要特别注意甚至要限制使用,不然可能会造成服务器负载越来越重而导致服务器崩溃的情况。

现在我们来利用appl1.jsp和appl2.jsp来演示Application的范围。代码不再列出,其和6.6节刚开始时的那个例子完全一样。让我们来看看执行结果。

当我们执行appl1.jsp以后,可以尝试任何操作。可以点击链接迁移到appl2.jsp,可以直接在地址栏中输入appl2.jsp的地址迁移,可以等上一段时间什么都不做,再重复做上边的操作,也可以直接把浏览器关掉,再打开新的浏览器窗口并直接在地址栏中输入页面appl2.jsp的地址迁移,最后,我们都只会得到一个结果,获得name和password属性的值,如图6.29所示。

图6.29

而当我们停止Tomcat后再启动,在地址栏中输入appl2.jsp的地址,并回车后发现,name和password的值无法获得了。如图6.30。

图6.30

好了,我们已经把四个范围介绍完了,总结一下,范围最小的是Page,它只能在本页面中使用;大一点的是Request,它可以在两个页面间使用;再大就是Session,只要浏览器窗口不关闭,就可以在任何页面直接使用;最大的是Application,只要服务器不停掉,任何地方都可以使用。

10Java Server Pages 隐式对象的更多相关文章

  1. JSP页面以及JSP九大隐式对象

    €JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. €JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比 ...

  2. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  3. JSP(工作原理,组成部分,指令标签,动作标签,隐式对象)

    目录 JSP JSP 什么是JSP JSP全名为Java Server Pages 中文名叫java服务器页面 它是在传统的网页HTML文件(.htm,.html)中插入Java程序段和JSP标记 后 ...

  4. jsp详解(3个指令、6个动作、9个内置对象、11个隐式对象)

    jsp概述SP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP实际上就是Servlet.    jsp=html+jav ...

  5. EL表达式中的11个隐式对象

    EL表达式中定义了11个隐式对象,使用这些隐式对象可以很方便地读取到Cookie.HTTP请求消息头字段.请求参数.Web应用程序中的初始化参数的信息,EL表达式中的隐式对象具体如下: 隐式对象 作用 ...

  6. JSP——JavaServer Page中的隐式对象(implicit object)、指令(directive)、脚本元素(scripting element)、动作(action)、EL表达式

    目录 1.JSP概述 2.注释(comment) 2.1.JSP注释 2.2.HTML注释 3.隐式对象(implicit object) 3.1.隐式对象清单 3.2.request对象 3.3.o ...

  7. JSP与EL隐式对象

    一,JSP隐式对象 隐式对象是可以直接使用的,无需声明.因为在JSP转译为servlet文件后,会自动声明其对象. 隐式对象① 说明 out 对应JspWriter对象,其内部关联一个PrintWri ...

  8. JSP 4个域对象-9个内置对象-11个EL隐式对象

    一. 四大域对象 1. PageContext :页面范围的数据 2. ServletRequest:请求范围的数据 3. HttpSession:会话范围的数据 4. ServletContext: ...

  9. jsp学习--JSP运行原理,九大隐式对象和JSP常用标签

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

随机推荐

  1. Servlet之中文乱码问题【入门版】

    请求数据的中文问题 1 post请求提交中文 get请求建议不提交中文(只是也有方法解决) 1.1post request.setCharacterEncoding("utf-8" ...

  2. iOS开发——基础篇——get和post请求的区别

    HTTP 定义了与服务器交互的不同方法,最常用的有4种,Get.Post.Put.Delete,如果我换一下顺序就好记了,Put(增),Delete(删),Post(改),Get(查),即增删改查,下 ...

  3. Bing必应地图中国API一显示地图 (转) 做人要厚道

    Bing必应地图中国API一显示地图 2011-05-24 14:27:31|  分类: Bing&Google|字号 订阅     微软必应地图中国地图API发布已经有10天了,考虑到网上现 ...

  4. Hadoop安装—— WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platf

    今天在安装hadoop完成测试创建用户目录失败在网上找到了原因记录一下原文地址 http://blog.csdn.net/l1028386804/article/details/51538611 配置 ...

  5. golang中管道热替换

    golang中管道替换问题 https://blog.csdn.net/cyk2396/article/details/78875347 1.运行以下代码: var chan1 chan int va ...

  6. windows 下操作目录(使用DOS命令)

    Attrib 更改单个文件或目录的属性.该命令设置或删除指派给文件或目录的只读.系统.存档.隐藏以及压缩属性. 含有下列参数的 attrib 命令仅当使用故障恢复控制台时才可用.含有不同参数的 att ...

  7. python-----查看显卡gpu信息

    需要安装pynvml库. 下载地址为:https://pypi.org/project/nvidia-ml-py/#history pip安装的命令为: pip install nvidia-ml-p ...

  8. 记录利用CSS完美解决前端图片变形问题

    在头条IT学堂看到CSS完美解决前端图片变形问题的文章,就记录分享下: 一.让图片的宽度或者高度等于容器的宽度或高度,多余的裁掉,然后让图片居中: <style type="text/ ...

  9. end()与andSelf()

    end() 回到最近的一个"破坏性"操作之前.即,将匹配的元素列表变为前一次的状态. 如 果之前没有破坏性操作,则返回一个空集.所谓的"破坏性"就是指任何改变所 ...

  10. ubuntu中 python升级 (转载)

    转自:http://blog.csdn.net/menglin8908/article/details/16822171 在ubuntu12.04中内置的python版本为2.7.3,最近想把pyth ...