什么是JSP内置对象
JSP引擎在调用JSP对应的jspServlet时,会传递或创建9个与web开发相关的对象供jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用
细心的朋友会发现,我们没有在JSP页面上定义过out对象,却可以直接使用!其实out对象就是JSP内置对象之一。
九个内置对象:
- pageContext
- page
- config
- request
- response
- session
- application
- exception
- out
out对象
out对象的API
int getBufferSize()【得到缓存大小】
int getRemaining()【得到未使用缓存的大小】
boolean isAutoFlush()
void println()
void flush()
void close()
void clearBuffer()
void clear()
out对象用于向浏览器输出数据,与之对应的是Servlet的PrintWriter对象。然而这个out对象的类型并不是PrintWriter,是JspWriter
我们可以简单理解为:JspWriter就是带缓存的PrintWrieter。
out对象的原理如下:
- 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
- 设置page指令的buffer属性关闭了out对象的缓存功能
- out对象的缓冲区已满
- 整个JSP页面结束
- 一般我们在JSP页面输出都是用表达式(<%=%>),所以out对象用得并不是很多!
request
- 内置对象request其实就是HttpServletRequest,在Servlet讲解的时候已经详细说明了,没什么好说的
response
- 内置对象response其实就是HttpServletResponse,在Servlet讲解的时候已经详细说明了,没什么好说的
config
- 内置对象config其实就是ServletConfig,在Servlet讲解的时候已经详细说明了,没什么好说的
session
- 内置对象session其实就是HttpSession。,在Servlet讲解的时候已经详细说明了,没什么好说的
注意:在page指令配置如下信息,session将不可使用
<%@page session="false" %>
application
- 内置对象application其实就是ServletContext对象,在Servlet讲解的时候已经详细说明了,没什么好说的
page
- 内置对象page是HttpJasPage对象,其实page对象代表的就是当前JSP页面,是当前JSP编译后的Servlet类的对象。也就是说:page对象相当于普通java类的this
exception
内置对象exception是java.lang.Exception类的对象,exception封装了JSP页面抛出的异常信息。exception经常被用来处理错误页面
前面我们已经讲过了怎么设置错误页面了,下面我们就来简单使用一下exception对象吧
-
1.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="error.jsp" %> <%--模拟空指针异常的错误--%><% String sss = null; sss.length();%>
* error.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
错误页面
<%
out.println("程序抛出了异常:" + exception);
%>
* 效果:
![image](http://upload-images.jianshu.io/upload_images/5291509-a3bd1c9994f6c38e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# pageContext
**pageContext是内置对象中最重要的一个对象,它代表着JSP页面编译后的内容(也就是JSP页面的运行环境)!**
## pageContext获取8个内置对象
* 既然它代表了JSP页面编译后的内容,理所当然的:**它封装了对其他8大内置对象的引用!**,也就是说,**通过pageContext可以获取到其他的8个内置对象!**
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
获取八大内置对象
<%
System.out.println(pageContext.getSession());
System.out.println(pageContext.getRequest());
System.out.println(pageContext.getResponse());
System.out.println(pageContext.getException());
System.out.println(pageContext.getPage());
System.out.println(pageContext.getServletConfig());
System.out.println(pageContext.getServletContext());
System.out.println(pageContext.getOut());
%>
* 看下效果:
[图片上传中...(image-c4d657-1517835716808-5)]
## pageContext作为域对象
* 类似于request,session,ServletContext作为域对象而言**都有以下三个方法**:
* **setAttribute(String name,Objcet o)**
* **getAttribute(String name)**
* **removeAttribute(String name)**
* 当然了,pageContext也不例外,**pageContext也有这三个方法**!
* pageContext本质上代表的是当前JSP页面编译后的内容,**作为域对象而言,它就代表着当前JSP页面(也就是page)**!也就是说:**pageContext域对象只在page范围内有效,超出了page范围就无效了**!
* 首先来看看在**page范围内能不能使用**
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用page域对象
<%
pageContext.setAttribute("name", "zhongfucheng");
%>
<%
String value = (String) pageContext.getAttribute("name");
System.out.println(value);
%>
* 效果如下:
[图片上传中...(image-3aff51-1517835716808-4)]
* 我们现在来试验一下**是不是超出了page范围就无效了!**
* **在2.jsp中request域对象设置属性**
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
request域对象设置属性
<%
//这是request域对象保存的内容
request.setAttribute("name","zhongfucheng");
%>
<%--跳转到1.jsp中--%>
* **企图在1.jsp中pageContext取出request存进去的属性**
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
在page域对象获取属性
<%
//企图获取request域对象存进的属性
String value = (String) pageContext.getAttribute("name");
System.out.println(value);
%>
* 效果如下:
![image](http://upload-images.jianshu.io/upload_images/5291509-45ede5abcdc5d248.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* * *
* pageContext本质上代表着编译后JSP的内容,**pageContext还可以封装了访问其他域的方法**!
* 上面的**pageContext默认是page范围的**,**但pageContext对象重载了set、get、removeAttribute这三个方法**
* **getAttribute(String name,int scope)**
* **setAttribute(String name,Object value,int scope)**
* **removeAttribute(String name,int scope)**
* **多了一个设置域范围的一个参数,如果不指定默认就是page**。当然了,**pageContext把request、session、application、page这几个域对象封装着了静态变量供我们使用**。
* **PageContext.APPLICATION_SCOPE**
* **PageContext.SESSION_SCOPE**
* **PageContext.REQUEST_SCOPE**
* **PageContext.PAGE_SCOPE**
* 刚才我们没有使用重载方法的时候,使用pageContext是无法获取到request域对象设置的属性的。**现在我们使用重载后的方法看一下能不能获取得到**!
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
在page域对象获取request域对象的属性
<%
//使用重载的方法获取request域对象的属性
String value = (String) pageContext.getAttribute("name",pageContext.REQUEST_SCOPE);
System.out.println(value);
%>
* 效果:
![image](http://upload-images.jianshu.io/upload_images/5291509-b28e3066227877cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* * *
* pageContexst还有这么一个方法:
* **findAttribute(String name)**
* **该方法会查找各个域的属性,从小到大开始寻找!也就是page—>request->session->application。**这个是EL表达式的原理!,EL表达式后面会讲到!
* 我们用此方法看能不能查找出request域对象的属性吧!
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
使用findAttribute
<%
//使用findAttribute查找2.jsp中request域对象的属性
String value = (String) pageContext.findAttribute("name");
System.out.println(value);
%>
* 效果如下:
![image](http://upload-images.jianshu.io/upload_images/5291509-eeb0da05e44a3a5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* * *
## 引入和跳转
PageContext类中定义了一个**forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法**。
* **pageContext.forward(String url)**
* **pageContext.include(String url)**
[图片上传中...(image-ef6a2c-1517835716807-0)]
* * *
# 4种属性范围
到目前为止,我们已经学了4种属性范围了。
1. **page【只在一个页面中保存属性,跳转页面无效】**
2. **requet【只在一次请求中保存属性,服务器跳转有效,浏览器跳转无效】**
3. **session【在一个会话范围中保存属性,无论何种跳转均有效,关闭浏览器后无效】**
4. **application【在整个服务器中保存,所有用户都可以使用】**
* * *
* 4个内置对象都支持以下的方法:
1. **setAttribute(String name, Object o )**
2. **getAttribute(String name)**
3. **removeAttribute(String name)**
## 应用场景
1. request:如果客户向服务器发请求,产生的数据,**用户看完就没用了,**像这样的数据就存在request域,像新闻数据,属于用户看完就没用的
2. session:如果客户向服务器发请求,产生的数据,**用户用完了等一会儿还有用**,像这样的数据就存在session域中,像购物数据,用户需要看到自己购物信息,并且等一会儿,还要用这个购物数据结帐
3. servletContext:如果客户向服务器发请求,产生的数据,**用户用完了,还要给其它用户用**,像这样的数据就存在servletContext域中,像聊天数据
> 如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,可以关注微信公众号:Java3y