1. JSP运行原理
每个JSP页面在第一次被访问时,Web容器斗湖吧请求交给JSP引擎(一个Java程序)去处理,JSP引擎先将JSP翻译成一个Servlet,然后按照Servlet的方式调用。
由于JSP第一次访问时会翻译成Servlet,所以第一次访问时通常会比较慢,但是第二次访问,JSP引擎发现JSP没有变化,就不在翻译,而是直接调用,程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的Servlet时,会创建9个与Web开发相关的对象,供翻译后的Servlet使用,在JSP页面中可以直接使用这些对象的引用。
2. 九大隐式对象
javax.servlet.http.HttpServletRequest request
javax.servlet.http.HttpServletResponse response
javax.servlet.jsp.PageContext pageContext
javax.servlet.http.HttpSession session
java.lang.Throwable exception
javax.servlet.ServletContext application
javax.servlet.ServletConfig config
javax.servlet.jsp.JspWriter out
java.lang.Object page
其中request、response、session、exception、config这几个前面已经介绍过,不在赘述。page代表当前页面,exception代表异常。下面主要介绍out和pageContext。
3. out隐式对象
out隐式对象用于向客户端发送文本数据。out对象是通过调用pageContext对象的getOut方法返回的,其作用和语法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
只有向out对象中写入内容,且满足如下任何一个条件时,out对象才去调用ServletRespon.getWriter方法,并通过该方法返回PrintWriter对象将out对象的缓冲区的内容真正的写到Servlet引擎提供的缓冲区中:
- 设置page指令的buffer属性,关闭了out对象的缓存内容
- out对象的缓冲区已满
- 整个JSP页面结束
4. pageContext对象
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其他8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及的一些常用操作,例如引入和跳转其他资源、检索其他域对象中的属性等。
4.1 通过pageContext获得其他对象
- getException方法返回exception隐式对象
- getPage方法返回page隐式对象
- getRequest方法返回request隐式对象
- getResponse方法返回response隐式对象
- getServletConfig方法返回config隐式对象
- getServletContext方法返回application隐式对象
- getSession方法返回session隐式对象
- getOut方法返回out隐式对象
pageContext封装其他8个内置对象的意义:
JSP应该只用来做数据输出,不应该出现Java代码,如果不可避免的需要写Java代码,可以使用自定义标签技术。实现自定义标签,需要针对自定义标签写一个Java类,如果要把JSP中的隐式对象都传给自定义标签的Java类,则需要传递8个对象。而有了pageContext则可以只传递一个对象,再通过它去获取其他8大隐式对象。
4.2 pageContext作为域对象
pageContext作为域对象,即page域,生命周期为当前的JSP页面。
pageContext对象方法:
public void setAttribute(String name, Object value) public Object getAttribute(String name) public void removeAttribute(String name) public Object findAttribute(java.lang.String name)
pageContext对象封装了访问其他域的方法:
public Object getAttribute(String name, int scope) public void setAttribute(String name, Object value, int scope) public void removeAttribute(String name, int scope)
代表各个域的常量:
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
4.3 引入和跳转到其他资源
pageContext类中定义了一个forword方法和两个include方法,分别用来简化和替代RequestDispatcher的forword方法和include方法。方法接受资源如果以“/”开头,“/”代表当前web应用。
pageContext.forword("/1.jsp");
pageContext.include("/header.jsp");