10Java Server Pages 隐式对象
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 隐式对象的更多相关文章
- JSP页面以及JSP九大隐式对象
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比 ...
- java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象
JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...
- JSP(工作原理,组成部分,指令标签,动作标签,隐式对象)
目录 JSP JSP 什么是JSP JSP全名为Java Server Pages 中文名叫java服务器页面 它是在传统的网页HTML文件(.htm,.html)中插入Java程序段和JSP标记 后 ...
- jsp详解(3个指令、6个动作、9个内置对象、11个隐式对象)
jsp概述SP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP实际上就是Servlet. jsp=html+jav ...
- EL表达式中的11个隐式对象
EL表达式中定义了11个隐式对象,使用这些隐式对象可以很方便地读取到Cookie.HTTP请求消息头字段.请求参数.Web应用程序中的初始化参数的信息,EL表达式中的隐式对象具体如下: 隐式对象 作用 ...
- 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 ...
- JSP与EL隐式对象
一,JSP隐式对象 隐式对象是可以直接使用的,无需声明.因为在JSP转译为servlet文件后,会自动声明其对象. 隐式对象① 说明 out 对应JspWriter对象,其内部关联一个PrintWri ...
- JSP 4个域对象-9个内置对象-11个EL隐式对象
一. 四大域对象 1. PageContext :页面范围的数据 2. ServletRequest:请求范围的数据 3. HttpSession:会话范围的数据 4. ServletContext: ...
- jsp学习--JSP运行原理,九大隐式对象和JSP常用标签
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
随机推荐
- [DevExpress]GridControl分页的实现
加入两个组件:BindingNavigator和BindingSource 代码: using System; using System.Collections.Generic; using Syst ...
- HTML DOM createTextNode() 方法
实例 创建一个文本节点: var btn=document.createTextNode("Hello World"); 输出结果: Hello World 尝试一下 » HTML ...
- android:模拟水波效果的自己定义View
Github地址:https://github.com/nuptboyzhb/WaterWaveView 欢迎Fork.欢迎Star 1.先看效果 watermark/2/text/aHR0cDovL ...
- HDU5806 NanoApe Loves Sequence Ⅱ
NanoApe Loves Sequence Ⅱ Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Ja ...
- YTU 2520: 小慧唱卡拉OK
2520: 小慧唱卡拉OK 时间限制: 1 Sec 内存限制: 128 MB 提交: 478 解决: 207 题目描述 小慧唱歌非常好听,小鑫很喜欢听小慧唱歌,小鑫最近又想听小慧唱歌了,于是小鑫请 ...
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...
- 【Silverlight】Bing Maps学习系列(四):使用图钉层(Pushpin layer)及地图图层(MapLayer)(转)
[Silverlight]Bing Maps学习系列(四):使用图钉层(Pushpin layer)及地图图层(MapLayer) 如果我们需要在Bing Maps中加入一个小图钉标记,该如何实现了? ...
- flask request 获取json内容2种方式
# -*- coding: utf-8 -*-from flask import request, jsonify, json, Moduleimport loggingfrom web.utils. ...
- Java 泛型 一
泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇将立足于代码介绍.总结了关于泛型的知识. 先看下面的代码: List list = new ArrayList(); list ...
- jQuery EasyUI,LinkButton(按钮)组件
转自:https://www.cnblogs.com/adc8868/p/6639570.html jQuery EasyUI,LinkButton(按钮)组件 学习要点: 1.加载方式 2.属性列表 ...