四种范围对象的作用域

pageContext:数据只在当前自身的页面有效;

request:数据在一次请求中有效;

session:数据在一次会话中有效;若是新开浏览器,则无效;

application:数据在当前Wed项目有效,可供所有用户共享。

以上的四种防卫对象都存在以下方法:

public void setAttribute(String name,Object o)    , 设置属性名和属性值;

public Object getAttribute(String name)  ,根据属性名,获取对应的属性值;

public void removeAttribute(String name) , 根据属性名,删除对应的属性值。

(1)pageContect作用域

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          pageContext.setAttribute("bookName", "Oracle数据库");
          pageContext.setAttribute("author", "小太阳");
       %>
                     书名:<%=pageContext.getAttribute("bookName") %><br/>
                     作者:<%=pageContext.getAttribute("author") %>  
</body>
</html>

因为pageContext对象中的属性的作用域是“在当前自身的页面内有效”,而以上均在同一个页面中增加或输出,所以能够正常显示。但将上面的页面做修改,将属性添加放在one.jsp中执行,再通过请求转发跳转到two.jsp页面,并在two.jsp中显示属性的值。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          pageContext.setAttribute("bookName", "Oracle数据库");
          pageContext.setAttribute("author", "小太阳");
          request.getRequestDispatcher("two.jsp").forward(request, response);
       %>
                    
</body>
</html>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>        
                     书名:<%=pageContext.getAttribute("bookName") %><br/>
                     作者:<%=pageContext.getAttribute("author") %>  
</body>
</html>

再次执行one.jsp,运行结果如下所示:

因为页面从one.jsp,通过请求转发跳转到two.jsp后,就已经不再是同一个页面了,所以无法再通过pageContext对象获取到数据。

(2)request作用域

要想请求转发后two.jsp页面获取到属性值,可以使用request的作用域。request的作用域是“在客户端向服务器端,发送的一次请求中有效”。可将上面的例子进行修改:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          request.setAttribute("bookName", "Oracle数据库");
          request.setAttribute("author", "小太阳");
          request.getRequestDispatcher("two.jsp").forward(request, response);
       %>                    
</body>
</html>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>        
                     书名:<%=request.getAttribute("bookName") %><br/>
                     作者:<%=request.getAttribute("author") %>  
</body>
</html>

因为从one.jsp到two.jsp的跳转是“请求转发”,即仍然是同一次请求,而request的作用域范围就是“在一次请求中有效”。

但要注意,如果将上例的“请求转发”改为"重定向"或超链接形式的跳转,则不会再获取到数据,如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          request.setAttribute("bookName", "Oracle数据库");
          request.setAttribute("author", "小太阳");         
       %>
       <a href="two.jsp">点我跳转</a> 
       <!--或改为重定向,跳转后的效果是一样的
         response.sendRedirect("two.jsp");
         -->                   
</body>
</html>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>        
                     书名:<%=request.getAttribute("bookName") %><br/>
                     作者:<%=request.getAttribute("author") %>  
</body>
</html>

点击跳转:

因为request的作用范围是“一次请求中有效”,而“重定向”或超链接形式的跳转,都是在跳转时重新发送了一次新的请求(重新去请求two.jsp),因此是获取不到数据的。

(3)session作用域

如果希望在增加属性之后,能够在跳转后的任何页面(无论是请求转发、重定向或超链接跳转),甚至是项目中任何一个页面都能获取到该属性值,就可以使用session的作用域来实现:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          session.setAttribute("bookName", "Oracle数据库");
          session.setAttribute("author", "小太阳");
          response.sendRedirect("two.jsp"); 
       %>    
       <!--或改为超链接,跳转后的效果是一样的
         <a href="two.jsp">点我啊</a>              
        -->
                   
</body>
</html>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>        
                     书名:<%=session.getAttribute("bookName") %><br/>
                     作者:<%=session.getAttribute("author") %>  
</body>
</html>

虽然“重定向”或超链接形式的跳转,会重新向服务器发送一次请求(重新去请求two.jsp),但仍然可以从session的作用域中获取到属性值。当然,如果通过请求转发实现的跳转,也能通过session获取到属性值。

此外,可重新打开同一个浏览器(相同浏览器),然后在新标签里直接输入并执行http://localhost:8080/pratical/two.jsp(执行了http://localhost:8080/pratical/one.jsp后),也能获取到数据:

但如果换了一个浏览器(不同的浏览器),在直接输入http://localhost:8080/pratical/two.jsp并执行(在另一个浏览器执行了http://localhost:8080/pratical/one.jsp后),结果:

也就是说,只要one.jsp中将属性添加到session后,凡是同一个浏览器都可以取到session中的该属性值;但如果换成其他浏览器,则就不能再在session中获取到该属性值了。

(4)application作用域

继续上面的讨论,如果向实现这样一个功能“只要在一个页面中增加了属性,那么即使重新换一个浏览器,也要能访问到该属性值”,该如何实现?答案就是application的作用域。将上例修改:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
       <%  
          application.setAttribute("bookName", "Oracle数据库");
          application.setAttribute("author", "小太阳");
          request.getRequestDispatcher("two.jsp").forward(request, response);
       %>    
       <!--或改为超链接,跳转后的效果是一样的
         <a href="two.jsp">点我啊</a>              
        -->
                   
</body>
</html>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>        
                     书名:<%=application.getAttribute("bookName") %><br/>
                     作者:<%=application.getAttribute("author") %>  
</body>
</html>

 

换一个浏览器输入http://localhost:8080/pratical/two.jsp(在另一个浏览器执行了http://localhost:8080/pratical/one.jsp后)并执行,也能获取到数据:

 

只要运行过一次one.jsp后,无论是一个浏览器标签,或者是更换新的浏览器,直接再运行two.jsp都能获取到数据。即只要是通过application.setAttribute()设置的属性,那么任何浏览器的任何页面都可以获取到该属性值,但是如果将tomcat服务器关闭,则application中的属性值就全部消失了。

可以利用application作用域的这一特性,来实现一个网页计数器功能,任何的浏览器都能访问,并统计次数:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>计数器</title>
</head>
<body>
       <%
          //第一次访问网页时,count没有值,所以是null
          Integer count = (Integer)application.getAttribute("count");
          if(count==null){
              //如果是第一次访问,将count赋值为1
              count = 1;
          }else{
              //如果不是第一次访问,则累加一次访问次数
              count = count+1;
          }
          //将访问次数的变量count保存在applition的属性count中,供下次访问时获取并累加
          application.setAttribute("count", count);
          out.print("你是第"+application.getAttribute("count")+"个人访问本网站的用户");
       %>
</body>
</html>

之后,无论是刷新当前页,还是打开一个浏览器标签,或者打开一个其他浏览器再次访问,没访问一次,访问次数就会累加一次。

需要说明的是,虽然四种作用域的大小依次是pageContext<request<session<application,但不能为了方便就随随便便使用范围大的范围对象,因为范围大造成的性能损耗就越大。因此,如果多个作用域都能完成相同的功能,一般会使用小的那个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值