在前面学写了JSP的概念,运行原理,相信大家对JSP技术也已经有了一定的了解,但是这还只揭开了JSP的一角面纱。JSP作为Sun公司在上世纪推出的动态网站开发的神兵利器,为了给JSP增加锋芒,可谓是用心良苦(sang xin bing kuang)。其中的一项,就是我们今天要讲的主角,隐式对象。
JSP隐式对象也称之为内置对象,是Sun公司为了方便Web应用程序开发,在JSP2.0规范中提供九个隐式对象给开发人员使用,JSP页面中默认创建,因此可以直接在JSP页面中使用。
在上图中,我们列举了JSP的9个隐式对象,从其对应的类型,我们可以看到其中有许多内置对象我们前面已经讲解过了,如request、response、config(ServletConfig)、session、application(ServletContext),如需使用,直接在jsp页面中的脚本元素中使用即可。示例代码如下所示:
<%
if(session.getAttribute("userName") != null){
out.print("欢迎:" + session.getAttribute("userName") + ",恭喜登录成功
");
} else{
out.print("登录已过期,请重新登录
");
out.print("重新登录");
}
%>
本文我们就着重介绍out、exception、pageContext这三个没有学过的内置对象。
其中的out对象与我们之前用过的PrintWriter功能非常相似,可以直接向客户端发送文本。不过两者还是有些区别的,我们先看下图:
我们可以看到,JspWriter的缓冲区和PrintWriter(通过response.getWriter获取的)的缓冲区是相互独立的,JspWriter缓冲区的内容在flush之后(如果为手动提交,页面最后会自动提交)才会提交到PrintWriter的缓冲区内。我们看如下例子:
<%
out.print("我是第一行打印的!
");
//out.flush();
response.getWriter().println("我是第二行打印的!
");
%>
页面运行结果如下,可以看到,out对象输出的内容反而在后,这是因为其在页面结束时才将JspWriter缓冲区的内容提交到PrintWriter的缓冲区内,当把上面out.flush()
取消注释后,我们就可以得到和我们预计顺序相同的结果。
在JSP页面中,因为也可使用Java代码,且设计之初,就承担重任,因此JSP页面中为了方便处理异常,就内置了exception对象来进行异常信息的处理。
exception对象的使用需要配合page指令中的errorPage、isErrorPage来使用。
我们来看一个例子,我们创建两个jsp页面,分别命名为exception.jsp、error.jsp,代码如下(注意两个页面中第一行的page指令):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="error.jsp"%>
exception Object Test
<%
int a = 3;
int b = 0;
%>
输出结果为:<%= (a / b) %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
错误页面
处理出错,错误信息为: <%= exception.getMessage() %>
浏览器中执行exception.jsp,执行结果如下如所示:
对于pageContext对象,我们放到域对象中来讲。
其实许多人会觉得,这些内置对象的默认创建,如果许多JSP页面中使用不到,不是会造成内存资源的浪费?其实,我们通过上图也可以看到,许多内置对象在应用中是全局唯一的,在JSP页面中创建的只是一个引用,因此并不会占用过多的资源。
域对象,顾名思义,就是可以存放数据的对象。大家可以回想下,在之前的学习中,有哪些对象是可以绑定属性(Attribute)的?其实还是很容易想到的,我们在学习Session的时候,就有提及过HttpServletRequest、ServletContext,当然HttpSession也可以绑定属性。
哇,一下说出来了三个。今天,我们就来学习最后这位神秘的域对象----PageContext。
PageContext对象也是一个内置对象,在jsp中会默认创建一个实例对象,名为pageContext,表示当前JSP页面的运行环境,并提供获取其他隐式对象的方法,方法列表如下:
不过这些方法用处不大,因为本身内置对象在JSP页面中就默认创建的,并可直接在JSP页面中使用,不过如果需要传参的话,则可只传递一个pageContextd对象即可,然后可以通过其获取其他隐式对象。
当然,PageContext作为域对象,其也提供了一些操作属性的方法,主要如下:
其中的scope为作用域大小,主要有如下定义:
/**
* Page scope: (this is the default) the named reference remains available
* in this PageContext until the return from the current Servlet.service()
* invocation.
*/
public static final int PAGE_SCOPE = 1;
/**
* Request scope: the named reference remains available from the
* ServletRequest associated with the Servlet until the current request
* is completed.
*/
public static final int REQUEST_SCOPE = 2;
/**
* Session scope (only valid if this page participates in a session):
* the named reference remains available from the HttpSession (if any)
* associated with the Servlet until the HttpSession is invalidated.
*/
public static final int SESSION_SCOPE = 3;
/**
* Application scope: named reference remains available in the
* ServletContext until it is reclaimed.
*/
public static final int APPLICATION_SCOPE = 4;
可以看到,PageContext作为压轴出场,果然没让让我们失望,其可以提供粒度可控的属性绑定,PageContext可以说是其他三个域对象的总和,并且可以提供范围更小的PAGE_SCOPE。
request域,在当前请求生命周期中有效,可以通过请求转发、请求包含来传递域中的属性。
因为HttpServlert继承了ServletRequest,因此也可以存储数据。其操作属性的方法如下:
//获取对应名称的属性,如果不存在则返回null
public Object getAttribute(String name);
//存储一个属性到此request
public void setAttribute(String name, Object o);
//从此request中删除一个属性
public void removeAttribute(String name);
session域,在一次会话周期内有效,主要用于保存会话信息。
其操作属性方法如下:
application域,其中的属性在整个Web应用中都可获取到(单个应用中)。
其操作属性方法如下:
Enumeration
的形式返回对应Servlet容器中可用的属性名称(其中的name)。本文主要讲解了JSP中的九大内置对象和四大域对象,因为许多内容都是之前博客中已经讲过了的,故只是简单的进行了描述,有兴趣的话可以阅读下方的参考文章。
又到了分隔线以下,本文到此就结束了,本文内容全部都是由博主自己进行整理并结合自身的理解进行总结,如果有什么错误,还请批评指正。
Java web这一专栏会是一个系列博客,喜欢的话可以持续关注,如果本文对你有所帮助,还请还请点赞、评论加关注。
有任何疑问,可以评论区留言。