目录
jsp九大隐式对象
什么是隐式对象?
当jsp被翻译成servlet时,service方法中有九个对象被定义并初始化,方便我们的调用,我们在将商品页面看不到他们,但是却可以在jsp的“<%%>”脚本中调用这些对象,这九个对象就是隐式对象。
隐式对象都有哪些?
九大隐式对象总结如下:
| 名称 | 类型 | 描述 |
| resquest对象 | javax.servlet.http.HttpServletRequest | 用于得到用户请求的信息 |
| response对象 | javax.servlet.http.HttpServletResponse | 用于发送服务器向客户端的回应信息 |
| config对象 | javax.servlet.ServletConfig | 服务器配置,可以取得初始化参数 |
| out对象 | javax.servlet.jsp.JspWrite | 用于页面输出 |
| session对象 | javax.servlet.http.HttpSession | 用于存储用户信息 |
| page对象 | java.Long.Object | 指当前页面转换成servlet类后的实例 |
| pageContext对象 | javax.servlet.jsp.PageContext | JSP的页面容器 |
| application对象 | javax.servlet.ServletContext | 所有用户的共享信息 |
| exception对象 | java.long.Throwable | 表示jsp页面的异常,只在错误页中起作用 |
这些隐式对象是哪里来的呢,首先,我们是在service方法中,所以我们本来就拥有resquest对象和response对象,那么剩下的对象是在哪里进行定义的呢,我们从翻译后的文件中找找答案:

可以看到,在jsp页面翻译后的servlet文件中的service方法中,自动的为我们创建好了这些对象,我们只需要进行使用即可。
但是仔细看,这里定义了六个对象,加上service方法中带的resquest和response对象,也才八个对象,还有一个对象呢?这个对象就是exception对象,它只会在错误页面中起作用,也就是说,只有在错误界面,才会有exception对象。
out对象
在9个隐式对象中,request、response、session等对象我们已经熟知,但是out对象在使用时会产生一个神奇的现象,我们就针对这个现象来说一说out对象。
首先我们新建一个jsp页面,在其中我们分别用四种页面输出方式进行内容的输出:

首先是直接输出1111111,然后通过response对象输出2222222,然后通过out对象输出3333333,最后通过<%=%>脚本输出4444444。让我们来看一下效果:

我们发现一个现象,在输出时,我的代码是依次写1234的,但是输出到页面就变成了2134的顺序,那这是为什么呢?
首先我们要知道,为了防止客户端压力过大,我们在往客户端发送信息时其实是先发进缓冲区中的,然后再由缓冲区发送到客户端。这里有两种缓冲区,out缓冲区和response缓冲区。我们使用response对象发送的信息直接发往response缓冲区,而其他三种方式发送的信息首先要先发到out缓冲区中,然后再发送到response缓冲区中,最后发往客户端。这就导致response对象发送的数据始终会快一步,这就造成了这种现象。
这种情况要避免也非常简单,在page指令中我们可以设置out缓冲区的大小,out缓冲区默认是8kb的缓存,我们可以通过buffer属性修改它的大小为0 ,这样就相当于不存在out缓冲区,信息就会依次发送到客户端了:

我们在page中修改buffer为0kb,然后重新运行看效果:

看到恢复正常了。
隐式对象在哪里使用
前面我们说,隐式对象是在service方法中被定义和初始化的,那么,只要是在service方法中,我们就可以使用隐式对象。在上一篇博客中我们说过,“<%%>”脚本中的内容会翻译在service方法中,同时“<%=%>”脚本中的内容会被翻译到service方法中的out.print()方法中去。所以这两个脚本中都可以使用隐式对象。
jsp标签
隐式对象我们已经大致了解,下面我们要说的是jsp标签。
什么是jsp标签?
jsp标签是用来控制jsp的行为的,执行一些常用的jsp页面动作,通过标签可以实现一些原本需要很多行java代码才能完成的事,比如请求转发等一些功能。
举一些例子;
页面包含:<jsp:include page ="被包含的页面">
请求转发:<jsp:forward page="要转发的资源">
需要注意的是,使用jsp标签所造成的页面包含是动态包含,不同于使用include指令所造成的静态包含。这两者有什么区别呢?
首先,静态包含时,被包含的页面中的内容是直接被翻译到包含页面的servlet中的,他自己是不会生成翻译后的Servlet文件的。而动态包含时,被包含的页面依旧会生成自己的Servlet文件,然后由包含页面来调用这个页面。
通过代码让大家更直观的感受下:

在这里我分别使用两种方法进行包含我们先看运行结果:

可以看到,两个页面都被包含进来了,效果看上去是一样的,下面我们打开翻译后的servlet文件看看有什么区别:

首先我们发现,只有index和include1两个页面进行了翻译,而静态包含的include并没有进行servlet翻译。下面我们看下index的翻译文件:

可以看到,静态包含页面的内容是直接翻译在out.write方法中输出的,而动态包含页面则是通过include方法进行调用的。
同时,使用jsp的请求转发标签可以快速的在jsp和jsp之间跳转,而不用再经过另外的servlet进行跳转了,十分的方便。
总结
不管是隐式对象还是jsp标签,亦或者包括上篇博客说的指令、脚本。这些产物都是为了方便我们的开发,我们在开发中需要灵活的运用他们,让自己的开发更高效、更便捷。