JSP的内置对象

一. 引入

1. JSP运行原理

(1) 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先

将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照Servlet的调用方式进行调用。

(2) 由于JSP第一次访问时会翻译成Servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP

没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。

(3) JSP引擎在调用JSP对应的_jspService时,会传递或创建9个与web开发相关的对象供_jspService使用。JSP技

术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在

JSP页面中通过这些变量就可以快速获得这9大对象的引用。

2. 什么是内置对象?

在JSP开发中,会频繁使用到一些对象。例如HttpSession,ServletContext,HttpServletRequet,这些对象都

是Servlet中的对象。如果我们每次要使用这些对象的时候都去创建这些对象就显得非常麻烦。所以Sun公司设计

JSP时,在JSP页面加载完毕之后就会自动帮开发者创建好这些对象,而开发者只需要直接使用这些对象调用方法

即可!这些创建好的对象就叫内置对象

3. 内置对象的原理

(1) 在执行JSP的翻译的时候,它会自动的帮我们翻译成创建对象的代码

(2) 举例:

①Servlet: HttpSession session = request.getSession(true); (需要开发者做)

②JSP:

tomcat服务器:HttpSession session = request.getSession(true);(不需要开发者做)

开发者做的直接用:session.getId();

4. 九大内置对象


二. out隐式对象

1. 简介

(1) out隐式对象用于向客户端发送文本数据。

(2) out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方

法返回的PrintWriter对象非常相似。

2. 细节

(1) out对象对应的类型是JspWriter类,相当于带缓冲的PrintWriter。

① PrintWriter类中的: 

     wrier(内容): 直接向浏览器写出内容。

② JspWriter类中的:

     writer(内容): 向JSP缓冲区写出内容。

(2) JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面

的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。 

3. JSP页面的缓冲机制


(1) 在Servlet中输出内容是不带缓冲的,当用户访问Servlet1时,就会调用PrintWriter的writer方法,把内容输

出到浏览器,直接输送,没有任何的中间环节。

(2) JSP中,如果一个用户访问了一个JSP页面,JSP页面中不建议用PrintWriter写,而是用JSP提供给我们的

JspWriter中的writer方法,它先把内容写到缓冲区,缓冲的功能就是为了提高效率,JspWriter缓冲区把内容输

出到PrintWriter对象中去,PrintWriter是不带缓冲区的,再由PrintWriter对象的writer方法输出到浏览器。

(3) 所以理论上,用JSP写出数据比Servlet效率要高。因为采用缓冲区后,当缓冲区满时才会写出。缓冲区的大小

默认是8KB。

(4) 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方

法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中。

(也就是说只要满足以下条件之一,缓冲区内容写出):

①关闭缓冲区,设置page指令的buffer属性关闭了out对象的缓存功能

②out对象的缓冲区已满

③刷新缓冲区

④执行完毕JSP页面,整个JSP页面结

4. out隐式对象的工作原理图


5. 实例

(1) 实例一

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"
	buffer="1kb"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>out对象</title>
	</head>
	<body>
		<%
			out.write("abc");
			response.getWriter().write("123");//运行结果是123 abc
		%>
	</body>
</html>

运行结果如下图所示:


(2) 实例二

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"
	buffer="1kb"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>out对象</title>
	</head>
	<body>
		<%
			out.write("abc");
			//手动刷新缓存
			out.flush();
			response.getWriter().write("123");//运行结果是abc123
		%>
	</body>
</html>

运行结果如下图所示:


(3) 实例三

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"
	buffer="0kb"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>out对象</title>
	</head>
	<body>
		<%
			out.write("abc");//buffer="0kb"就意味着关闭缓存
			response.getWriter().write("123");//运行结果是abc123
		%>
	</body>
</html>

运行结果如下图所示:


(4) 实例四

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" buffer="1kb"%><%
		for(int i=1;i<=1023;i++){
    		out.write("a");
    	}
    	//查看缓存区大小
    	System.out.println("当前缓存区大小:"+out.getBufferSize());
    	//查看缓存区剩余大小
    	System.out.println("缓存区剩余大小:"+out.getRemaining());
    	//刷新缓存
    	//out.flush();
    	response.getWriter().write("123");
     %>
  </body>
</html>

运行结果如下图所示:



三. pageContext对象

1. 简介

(1) pageContext对象的类型是PageContext,叫JSP的上下文对象。

(2) pageContext对象是JSP技术中最重要的一个对象,它代表当前JSP页面的运行环境,这个对象不仅封装了对

其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经

常涉及到的一些常用操作,例如包含和跳转其它资源、检索其它域对象中的属性等。

2. 用途一:通过pageContext可以获取其他八个内置对象

(1) 伪代码理解

public class 01_hello_jsp {
	public void _jspService(request,response){
		创建内置对象
		HttpSession session =....;
		ServletConfig config = ....;

		//SUN公司把8个经常使用的内置对象封装到PageContext对象中
		PageContext pageContext  = 封装;
		//调用method1方法
	        method1(pageContext);
	}
					
	public void method1(PageContext pageContext){
		//希望在这个方法内部使用内置对象,但是不能在method1中使用,因为上面的内置对象都是局部变量,所以在下面的方法内部使用局部变量是不可能的。可以从PageContext对象中获取其他8个内置对象
		JspWriter out = pageContext.getOut();
		HttpServletRequest rquest = pageContext.getRequest();
		........
	}
}

(2) 通过pageContext获得其他对象


(3) 使用场景:在自定义标签的时候,PageContext对象频繁使用到!

(4) 实例:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>
    <%
    	//作用1:pageContext可以获取其他8个内置对象
    	response.getWriter().write("是否相等?"+(out==pageContext.getOut()) +"<br/>");
    	response.getWriter().write("是否相等?"+(session==pageContext.getSession()));
     %>
  </body>
</html>

运行结果如下图所示:


3. 用途二:pageContext可以作为域对象用于共享数据

(1) 常量及方法


(2) 域范围常量:

① PageContext.PAGE_SCOPE

② PageContext.REQUEST_SCOPE

③ PageContext..SESSION_SCOPE

④ PageContext.APPLICATION_SCOPE 

(3) 保存数据

① 默认情况下,保存到page域:pageContext.setAttribute("name");

② 可以向四个域对象保存数据:pageContext.setAttribute("name",域范围常量);

(4) 获取数据

① 默认情况下,从page域获取:pageContext.getAttribute("name");

② 可以从四个域中获取数据:pageContext.getAttribute("name",域范围常量);

③ 自动在四个域中搜索数据:pageContext.findAttribute("name");

搜索顺序:page域 -> request域 -> session域- > context域(application域)。

(5) 实例:

① 实例一:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>
     <%-- pageContext作为域对象使用, 可以往不同域对象中存取数据 --%>
      <%
      	//第一步:保存数据。默认情况下,保存在page域中
      	pageContext.setAttribute("message","page's message");
       %>
       
       <%
       	//第二步:获取数据,page只能在当前页面获取。
       	String message = (String)pageContext.getAttribute("message");
       	out.write(message);
        %>  
  </body>
</html>

运行结果如下图所示:


② 实例二:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>
     <%-- pageContext作为域对象使用,可以往不同域对象中存取数据 --%>
      <%
      	pageContext.setAttribute("message", "page's message");
      	pageContext.setAttribute("message","request's messsage",PageContext.REQUEST_SCOPE);//保存到request域中
      	//request.setAttribute("message","request's message"); 等价于上面的代码
      	pageContext.setAttribute("message","session's messsage",PageContext.SESSION_SCOPE);//保存到sessio域中
      	pageContext.setAttribute("message","application's messsage",PageContext.APPLICATION_SCOPE);//保存到context域中
       %>
 
        <%-- 从request域中取出数据 --%>
        <%=request.getAttribute("message") %><br/>
        <%-- 原则: 在哪个域中保存数据,就必须从哪个域取出数据!!! --%>
        <%=pageContext.getAttribute("message",PageContext.PAGE_SCOPE) %><br/>
        <%=pageContext.getAttribute("message",PageContext.REQUEST_SCOPE) %><br/>
        <%=pageContext.getAttribute("message",PageContext.SESSION_SCOPE) %><br/>
        <%=pageContext.getAttribute("message",PageContext.APPLICATION_SCOPE) %><br/>
        <hr/>
  </body>
</html>

运行结果如下图所示:


③ 实例三:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>
     <%-- pageContext作为域对象使用,可以往不同域对象中存取数据 --%>
      <%
      	pageContext.setAttribute("message", "page's message");
      	pageContext.setAttribute("message","request's messsage",PageContext.REQUEST_SCOPE);//保存到request域中
      	//request.setAttribute("message","request's message"); 等价于上面的代码
      	pageContext.setAttribute("message","session's messsage",PageContext.SESSION_SCOPE);//保存到sessio域中
      	pageContext.setAttribute("message","application's messsage",PageContext.APPLICATION_SCOPE);//保存到context域中
       %>
 
        <%-- 更方便的取数据的方法,因为保存的都是message --%>
        <%-- findAttribute(): 在四个域中自动搜索数据。顺序: page域 -> request域  -> session域 -> context域 --%>
        <%=pageContext.findAttribute("message") %>
        <hr/>
  </body>
</html>

运行结果如下图所示:


4. 用途三:引入和跳转到其他资源

(1) PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法;

(2) 传递给这些方法的资源路径,如果路径以“/”开头,表示相对于当前WEB应用程序的根目录,否则,表示相

对于当前JSP所映射到的访问路径。

(3) 如果想把数据从一个资源发到另外一个资源,前提是使用重定向技术,此时只能使用Session域和context

域;(重定向是不能从request中带数据的);此时分析这个数据是浏览器特有的还是全局的?

(4) 实例:

① 转发

保存数据:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>  
     <%-- pageContext作为域对象使用,可以往不同域对象中存取数据 --%>
      <%
      	pageContext.setAttribute("message", "page's message");
      	pageContext.setAttribute("message","request's messsage",PageContext.REQUEST_SCOPE);//保存到request域中
      	//request.setAttribute("message","request's message"); 等价于上面的代码
      	pageContext.setAttribute("message","session's messsage",PageContext.SESSION_SCOPE);//保存到sessio域中
      	pageContext.setAttribute("message","application's messsage",PageContext.APPLICATION_SCOPE);//保存到context域中
       %>
       
        <%
      	//转发
      	request.getRequestDispatcher("/05.pageContext2.jsp").forward(request,response);
       %>
  </body>
</html>

获取数据:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>从四个域中获取数据</title>  
  </head>
  
  <body>
    page域:<%=pageContext.getAttribute("message",PageContext.PAGE_SCOPE) %><br/>
    request域: <%=pageContext.getAttribute("message",PageContext.REQUEST_SCOPE) %><br/>
    session域: <%=pageContext.getAttribute("message",PageContext.SESSION_SCOPE) %><br/>
    context域:<%=pageContext.getAttribute("message",PageContext.APPLICATION_SCOPE) %><br/>
  </body>
</html>

运行结果如下图所示:


② 重定向

保存数据:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" 
isErrorPage="true" 
session="true"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>pageContext对象</title>  
  </head>
  
  <body>  
     <%-- pageContext作为域对象使用,可以往不同域对象中存取数据 --%>
      <%
      	pageContext.setAttribute("message", "page's message");
      	pageContext.setAttribute("message","request's messsage",PageContext.REQUEST_SCOPE);//保存到request域中
      	//request.setAttribute("message","request's message"); 等价于上面的代码
      	pageContext.setAttribute("message","session's messsage",PageContext.SESSION_SCOPE);//保存到sessio域中
      	pageContext.setAttribute("message","application's messsage",PageContext.APPLICATION_SCOPE);//保存到context域中
       %>
       
        <%
      	//重定向
      	response.sendRedirect(request.getContextPath()+"/05.pageContext2.jsp");
       %>
  </body>
</html>

获取数据:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head> 
    <title>从四个域中获取数据</title>  
  </head>
  
  <body>
    page域:<%=pageContext.getAttribute("message",PageContext.PAGE_SCOPE) %><br/>
    request域: <%=pageContext.getAttribute("message",PageContext.REQUEST_SCOPE) %><br/>
    session域: <%=pageContext.getAttribute("message",PageContext.SESSION_SCOPE) %><br/>
    context域:<%=pageContext.getAttribute("message",PageContext.APPLICATION_SCOPE) %><br/>
  </body>
</html>

运行结果:


四. 补充:域对象

1. Servlet中的三个域对象

(1) ServletContext-------context域

(2) HttpServletRequet---request域

(3) HttpSession----------session域 

2. JSP中的四个域对象

(1)pageContext-------page域

(2)request-------------request域

(3)session-------------session域

(4)ServletContext-----application域(context域)

3. 域对象的作用:

域对象可以保存数据和获取数据,用于数据共享。

4. 域对象中的方法:

(1) setAttribute("name",Object)---保存数据

(2) getAttribute("name")---获取数据

(3) removeAttribute("name")---清除数据

5. 域对象作用范围:

(1) page域:只能在当前JSP页面中使用(当前页面);

(2) request域:只能在同一个请求中使用(转发);

(3) session域:只能在同一个会话(session对象)中使用(私有的),只要不关闭浏览器,那么这个session就

一直存在;

(4) context域:只能在同一个web应用中使用。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

处女座的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值