JSP运行原理与JSP隐式对象(9个)

来源:互联网 发布:软件开发的课程 编辑:程序博客网 时间:2024/06/15 06:05
摘要: 摘自《深入体验JAVA WEB开发内幕——核心基础》,如有版权问题,请联系我。

一、JSP运行原理

Web容器(Servlet引擎)接收到.jsp为扩展名的URL访问请求时,它将把该访问请求交给JSP引擎去处理,JSP引擎负责解释和执行JSP页面。

当Web容器接收到客户端的访问请求时,它将根据请求的URL在web.xml配置文件中查找匹配<servlet-mapping>元素,然后将请求交给元素中指定的servlet程序去处理,打开Tomcat下conf\web.xml文件可以发现以.jsp为扩展名的访问请求实际由JspServlet负责处理。

每个JSP页面在第一次被访问时,JSP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的class文件,然后再由Servlet引擎像调用普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的servlet程序。

将JSP页面翻译成Servlet程序后再运行的机制有一个明显的好处,那就是JSP引擎仅需要将JSP页面翻译为Servlet程序,而与客户端的交互过程仍然由Servlet引擎来处理,重复利用了已有的Servlet引擎技术。


二、在JSP程序使用out.print与out.write的区别

print系列方法可将各种类型的数据转换成字符串的形式输出;write系列方法只能输出字符、字符数组和字符串等与字符相关的数据。

在<%= %>的表达式相当于在<% %>使用out.printl()方法。


三、JSP隐式对象(9个)

1、9个隐式对象介绍

JSP提供了9个预先定义的变量,这些变量也被称为隐式对象,某些书籍则称为JSP内部对象。这9个隐式对象分别是:

  • config,ServletConfig类型的实例对象

  • application,ServletContext类型的实例对象

  • request,作为_jspService(可以认为就相当于HttpServlet中的service方法)方法的参数(HttpServletRequest request)传递进来的

  • response,作为_jspService方法的参数(HttpServletResponse response)传递进来的

  • session,HttpSession的实例对象

  • page,对象的类型为Object,它被赋值为this,即代表JSP页面所编译成的Servlet对象自身,当前用处不大

  • exception,该对象只能在处理错误的JSP页面中使用,后面讲解

以及——

  • out对象

  • pageContext对象


2、out对象

out对象是通过调用pageContext对象的getOut方法返回的,其作用及用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似,但out隐式对象类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。

只有向out对象中写入了内容,且满足以下任何一个条件,out对象才会去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:

  • 设置page指令的buffer属性关闭了out对象的缓存功能

  • 写入到out对象中的内容充满了out对象的缓冲区

  • JSP页面结束

(1)

<%    out.println("first line<br>");    response.getWriter().println("second line<br>");%>

用浏览器访问,发现显示结果为:

second line

first line

这是因为out.println语句只是把内容写入到了out对象的缓冲区中,直到整个JSP页面结束时,out对象才把它的缓冲区里面的内容真正写入到Servlet引擎提供的缓冲区中,而response.getWriter.println语句则是真正把内容写入到Servlet引擎提供的缓冲区中。

(2)

<%    ServletOutputStream sos = response.getOutputStream();    sos.println("www.baidu.com");%>

如果在<%前面或最后的%>后面输入了任意字符,访问该JSP页面会报异常。因为位于JSP脚本元素之外的任何字符文本,在JSP页面所翻译成的Servlet程序中以out.write方法输出到客户端。由于只要向out对象写入了内容,它就会在JSP页面结束时调用getWriter方法,这就与getOutputStream方法发生了冲突。


3、pageContext对象

(这里就知道jsp-api包是干什么的?如果没有这个包,jsp页面根本不认识pageContext这个预定义对象)

pageContext对象封装了当前JSP页面的运行信息,它提供了返回JSP页面的其他隐式对象的方法。PageContext类中定义了一个setAttribute方法来将对象存储进pageContext对象内部的一个HashMap对象中,同时定义了一个getAttribute方法来获取存储在HashMap对象中的对象,以便在JSP页面与调用的普通Java类之间传递对象信息。PageContext除了可以存储和检索自身的属性对象外,还定义了可以检索其他域范围内的属性对象的方法。

(1)、获得其他隐式对象:

  • getException

  • getPage

  • getRequest

  • getResponse

  • getServletConfig

  • getServletContext

  • getSession

  • getOut

(2)、引入和跳转到其他资源

PageContext类中定义了一个forward和两个include方法来简化和替代RequestDispatcher.forward方法和RequestDispatcher.include方法的调用,完整定义为:

public void forward(String relativeUrlPath) throws ...Exceptionpublic void include(String relativeUrlPath) throws ...Exceptionpublic void include(String relativeUrlPath, boolean flush) throws ...Exception

传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相对于当前Web应用程序的根目录,否则表示相对于当前JSP所映射的访问路径。

第一个include方法在引入资源前先将out对象中的内容刷新到Servlet引擎提供的缓冲区中;第二个include方法则通过一个参数来决定在引入资源前是否刷新out对象中的内容。

forward方法在将请求转发给其他资源之前,先清空out对象中已写入的内容,然后调用RequestDispatcher.forward方法执行请求转发。

(3)访问各个域范围的属性

在application、session、request、pageContext对象中都可以调用setAttribut方法和getAttribute方法来设置和检索属于各自域范围内的属性。存储在application对象中的属性可以被同一个Web应用程序中的所有Servlet和JSP页面访问;存储在session对象中的属性可以被属于同一个会话的所有Servlet和JSP页面访问;存储在request对象中的属性可以被属于同一个请求的所有Servlet和JSP页面访问。存储在pageContext对象中的属性仅可以被当前JSP页面的当前响应过程(下次响应则不同)的各个组件访问。

此外,PageContext类中还提供了对各个域范围的属性进行统一管理的方法。

  • setAttribute方法

两种重载形式:

setAttribute(String name, Object o) // 默认把对象存储在page域范围(就是存储到pageContext对象)中

setAttribute(String name, Object o, int scope) //scope表示把对象存储进指定的域范围,PageContext定义了4个整数常量,分别是APPLICATION_SCOPE,SESSION_SCOPE,REQUEST_SCOPE,PAGE_SCOPE

  • getAttribute方法(两种)

  • removeAttribute方法(两种)

  • findAttribute方法

用于依次从page、request、session、application域范围查找某个指定名称的属性,找到则返回指定对象,否则返回null。

0 0
原创粉丝点击