由来:在jsp开发中,会频繁使用到一些对象 。例如HttpSession,ServletContext,ServletContext,HttpServletRequet。所以Sun公司设计Jsp时,在jsp页面加载完毕之后就会自动帮开发者创建好这些对象,开发者只需要直接使用这些对象调用方法即可!这些创建好的对象就叫内置对象,一共有九个。

内置对象名 类型
request HttpServletRequest
 response  HttpServletResponse
config ServletConfig
application ServletContext
session Httpsession
exception Thrwable(错误处理页面)
page Object(this:当前jsp翻译的类如我们上次写到的hello.jsp翻译变成了hello_jsp.java中的生命周期方法)
out JspWriter
pageContext pageContext

我们可以随便打开一个以jsp翻译的java源文件

public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null; try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out; String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; }

  从上面可以看到内置对象都是在service方法中创建的,而指令和声明是成员变量和方法,故不能在指令和声明中使用内置对象


1、out对象

  是jspWriter类,相当于带缓存的PrintWriter。有点与PrintWriter方法相似

如果我们在jsp页面执行以下代码会发现

<%
out.write("abc");
response.getWriter().write("2222223");
%>

因为out中添加了缓冲区的设置,所以在浏览器中先打印出后面的语句,前面的要等其缓冲区(默认大小是8kb)没有满,要等jsp页面执行完之后才打印,我们也可以去手动刷新页面

         

我们可以在jsp的指令部分去设置缓冲区大小

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" buffer="8kb"%>

我们继续做实验,在jsp页面运行如下的代码

<%
out.write("abc");
//查看缓冲区的大小
System.out.println("当前缓冲区的大小:"+out.getBufferSize());
System.out.println("当前缓冲区的剩余大小:"+out.getRemaining());
%>

看到的结果是这样的:

我们在浏览端发送了只有“abc”这样3个字节,却是用了两百多个字节的大小,多余的部分去哪了呢?这个时候我们可以全看看out_jsp.java文件,

 out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <base href=\"");
out.print(basePath);
out.write("\">\r\n");
out.write(" <title>My JSP 'out.jsp' starting page</title>\r\n");
out.write(" </head>\r\n");
out.write(" <body>\r\n");
out.write(" \t"); out.write("abc");
//查看缓冲区的大小
System.out.println("当前缓冲区的大小:"+out.getBufferSize());
System.out.println("当前缓冲区的剩余大小:"+out.getRemaining()); out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");

其实我们会发现,我们向浏览发送字节远不止abc,其实还有一些标签等的内容,他们是要发送到浏览器端,也是占大小的。

我们再来做一个实验,如下代码,

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" buffer="1kb"%>
<%
System.out.println(out.getRemaining());
for(int i=1;i<=1024;i++)
out.write("a");
//查看缓冲区的大小
response.getWriter().write("郭庆兴");
%>

看到这个时候的效果:

不知道为什么我这里出现了一开始的缓冲区大小是1022(我设置了应该是1kb buffer="1kb"),但是这不是我的重点,重点是他这个图说明了缓冲区的运行机制,如果缓冲区满了,就立即将其打印出来,没有满,就等待页面执行完才打印,就像第一次1022缓冲区满了之后去打印,然后又重新往里放两个a,此时缓冲区没有满,就必须等待jsp页面加载完后执行,所以出现在“郭庆兴”的后面出现。

(我发现不知道哪里用了两个字节使得一开始的缓冲区大小只有1022B,我有试了buffer="2kb"和buffer="3kb",发现其剩余大小都正常)

2、exception 对象

该对象表示其他页面所抛出的异常对象(Throwable对象)

我们打开jsp翻译后的java源文件发现,在该文件的service方法中居然里面八大内置对象都存在,就唯独没有该对象,这是因为我们没有指定其为错误处理页面,只有指定当前页面为错误错里页面后才可以去使用它。

3、pageContext对象

jsp的上下文对象,为了我们更方便的去使用其他八个内置对象。

(例如当我们要在service方法之外去调用session对象或者request对象等,)

public void _jspService(request,response){

创建内置对象

HttpSession session =....;

ervletConfig config = ....;

    把8个经常使用的内置对象封装到PageContext对象中

PageContext pageContext  = 封装;

调用method1方法(如果将这八个内置对象一个一个的作为参数传递给下面的方法,显然过于麻烦,这个时候我们可以使用已经封装好了的pageContext作为参数传递过去明显就简单多了)

method1(pageContext);

}

public void method1(PageContext pageContext){

希望使用内置对象

从PageContext对象中获取其他8个内置对象

JspWriter out =pageContext.getOut();

HttpServletRequest rquest = pageContext.getRequest();

........

}

注意:pageContext也是一个域对象,已经有四个域对象了:request,servletContext,还有session,现在又有pageContext,(cookie不是域对象,而是将数据发送到浏览器端保存),那么现在servlet已经有三个域对象了,而jsp有四个域对象(jsp就是一个servlet)。

#保存数据

1)默认情况下,保存到page域

pageContext.setAttribute("name");

2)可以向四个域对象保存数据

pageContext.setAttribute("name",域范围常量)

#获取数据

  1)、默认情况下,从page域获取

pageContext.getAttribute("name")

  2)、可以从四个域中获取数据

      pageContext.getAttribute("name",域范围常量)

          PageContext.PAGE_SCOPE (page域)

  PageContext.REQUEST_SCOPE(request域)

PageContext..SESSION_SCOPE(session域)

PageContext.APPLICATION_SCOPE(aplication域:即servletContext)

  3)、自动在四个域中搜索数据

pageContext.findAttribute("name");

    如果有相同的名字,则按照顺序:page域 -> request域 -> session域- > context域(application域)  

我们可以来对pageContext来做实验

<%
//pageContext作为域对象去保存数据
pageContext.setAttribute("message", "i am coming");
pageContext.setAttribute("message", "我是pageContext中设置的request域中的值,i am coming", pageContext.REQUEST_SCOPE);
//request.setAttribute("name", "gqxing"); //等价于上面的代码 request.setAttribute("value", "request's value");
%>
<hr>
<%--
原则:在那个域中保存数据,必须在哪个域中取数据。
--%>
<%
//获取数据
String message=(String)pageContext.getAttribute("message");
out.print(message+"<hr>");
String name=(String)request.getAttribute("message");
out.print(name);
%> <hr>
<span>用pageContext中的request域去取request域中设置的值(request.setAttribute("value", "request's value");)</span>
<% String value=(String)pageContext.getAttribute("message", pageContext.REQUEST_SCOPE);
out.print(value);
%>
<hr><span>用findattribute去查找:</span>
<%--
findAttribute:自动搜索功能
顺序:page域(pageContext)——>request域——>session域——>application域。
--%>
<%
String name3=(String)pageContext.findAttribute(message);
out.print(name);
%>

  结果如图所示:


关于四种域对象的理解

可以来试着去辨别各自的区别(jsp的四个域对象的作用范围)

page域(pageContext):只能作用于当前页面,既不能用来做做转发的数据分享,也不能做重定向的数据分享

request域:只能作用于同一个请求的数据共享,所以只能在请求的转发中使用

session域:只能作用于一次对话中共享数据(一次对话:用户打开浏览器,浏览多个web站点后,关闭该浏览器),转发和重定向都可以使用

context域(application):只能在同一个web应用中使用。(全局的)

我们可以做如下的实验:

先用请求的转发做一个实验,如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>My JSP 'demo4.jsp' starting page</title>
</head>
<body>
<%--数据的保存面 --%>
<%pageContext.setAttribute("messsage", "page'vale",pageContext.PAGE_SCOPE);
pageContext.setAttribute("message", "request'value",pageContext.REQUEST_SCOPE);
pageContext.setAttribute("message", "session'value",pageContext.SESSION_SCOPE);
pageContext.setAttribute("message", "context'value", pageContext.APPLICATION_SCOPE);
%>
<%
request.getRequestDispatcher("/demo5.jsp").forward(request, response);
%>
</body>
</html>

  然后在另一个页面去接受数据

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
page:<%=pageContext.getAttribute("message") %>
<hr>
request:<%=pageContext.getAttribute("message",pageContext.REQUEST_SCOPE) %>
<hr>
session:<%=pageContext.getAttribute("message",pageContext.SESSION_SCOPE) %>
<hr>
application(context):<%=pageContext.getAttribute("message",pageContext.APPLICATION_SCOPE) %>
</body>
</html>

 最后发现结果如图所示:

当我们将转发方式改为重定向的时候,如下:

response.sendRedirect(request.getContextPath()+"/demo5.jsp");

这时结果如图:

Jsp(3):内置对象和四种域对象的理解的更多相关文章

  1. JSP的执行原理、JSP的内置对象、四大作用域解析、MVC模式理解>从零开始学JAVA系列

    目录 JSP的执行原理.JSP的内置对象.四大作用域解析.MVC模式理解 JSP的执行原理 这里拿一个小例子来解析JSP是如何被访问到的 首先将该项目部署到tomcat,并且通过tomcat启动 通过 ...

  2. JSP的内置对象以及作用域。

    最近在面试,一些基础的问题总是会被问到,虽然是基础,但是有些东西在工作中用的少,所以就有些记不清了,在面试的时候更因为紧张很容易造成原先知道的知识也会突然忘了的情况发生.所以在重新组织一下jsp的内置 ...

  3. JSP的内置对象(上)

    1.JSP内置对象的概念:JSP的内置对象时Web容器所创建的一组对象,不使用new关键字就可以使用的内置对象 2.JSP九大内置对象内置对象:out ,request ,response ,sess ...

  4. JSP&EL 内置对象

    JSP&EL 内置对象 转载▼   具体的JSP和El中的内置对象见下表,由于我写在了excel中,也不知道怎么把excel发出来,就截了图. 相关问题: Q1: JSP:EL中 pageCo ...

  5. struts访问jsp api内置对象的集中方式

    1 default-action-ref元素改元素用来配置默认的action,如果struts找不到对应的action,就会调用这个默认的action 2 dmi处理方式是通过请求action中的一个 ...

  6. 什么是jsp?jsp的内置对象有哪些?

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [什么是jsp? ...

  7. javaWEB中的四种域对象

    javaWEB中的四种域对象 (1)ServletContext ServletContext是最大的Web域对象,在整个工程内有效,可以存储一些需要全局部署的配置文件,也可以存储其他信息,不过因为它 ...

  8. python 迭代器(一):迭代器基础(一) 语言内部使用 iter(...) 内置函数处理可迭代对象的方式

    简介 在 Python 中,所有集合都可以迭代.在 Python 语言内部,迭代器用于支持: 1.for 循环2.构建和扩展集合类型3.逐行遍历文本文件4.列表推导.字典推导和集合推导5.元组拆包6. ...

  9. JSP的内置对象application、session、request、page的作用域

    1.application内置对象的类型名称为ServletContext. 2.session内置对象的类型名称为HttpSession. 3.application作用域:对应整个应用上下文. a ...

随机推荐

  1. VS2015 + QT5.7 中文的坑

    试验1: #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endif #include < ...

  2. 例行性工作排程 (crontab)

    1. 什么是例行性工作排程 1.1 Linux 工作排程的种类: at, crontab 1.2 Linux 上常见的例行性工作2. 仅运行一次的工作排程 2.1 atd 的启动与 at 运行的方式: ...

  3. 修改UISearBar的文字颜色,placehoder颜色及输入框颜色

    UISearchBar是我们经常会用到的一个控件-- 它由两个subView组成的,一个是UISearchBarBackGround,另一个是UITextField UITextField默认输入字体 ...

  4. Python 类 setattr、getattr、hasattr 的使用

    #coding=utf-8 class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = n ...

  5. shell 基础 $(cd `dirname $0`;pwd)

    $ cd `dirname $0` 和PWD%/* shell变量的一些特殊用法 在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的"." ...

  6. Python Web 性能和压力测试 multi-mechanize

    http://www.aikaiyuan.com/5318.html 对Web服务做Performance & Load测试,最常见的工具有Apache Benchmark俗称ab和商用工具L ...

  7. fzu 2037 Maximum Value Problem

    http://acm.fzu.edu.cn/problem.php?pid=2037 思路:找规律,找出递推公式f[n]=f[n-1]*n+(n-1)!,另一个的结果也是一个递推,s[n]=s[n-1 ...

  8. Android 模拟登陆 保存密码(信息)到手机中 文件信息读取

    package com.wuyou.login; import java.io.IOException; import java.util.Map; import android.app.Activi ...

  9. 【HDU 4372】 Count the Buildings (第一类斯特林数)

    Count the Buildings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  10. ORACLE数字转换人民币大写

    ORACLE 数字转换人民币大写     示例.   数字                    :183066999230.68 人民币大写        :壹仟捌佰参拾亿陆仟陆佰玖拾玖万玖仟贰佰参 ...