已阅读5页,还剩45页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
心提示:2.9 JSP脚本中的9个内置对象 JSP脚本中包含9个内置对象,这9个内置对象都是Servlet API接口的实例,只是JSP规范将它们完成了默认初始化(由JSP页面对应Servlet的_jspService()方法来创建这些实例)。也就是说,它们已经是对象,可以直接使用。9个内置对象依 2.9 JSP脚本中的9个内置对象JSP脚本中包含9个内置对象,这9个内置对象都是Servlet API接口的实例,只是JSP规范将它们完成了默认初始化(由JSP页面对应Servlet的_jspService()方法来创建这些实例)。也就是说,它们已经是对象,可以直接使用。9个内置对象依次如下: application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于JSP页面,或者Servlet之间交换信息。常用的方法有getAttribute(String attName)、setAttribute(String attName , String attValue)和getInitParameter(String paramName)等。 config:javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息。常用的方法有getInitParameter(String paramName)和getInitParameternames()等方法。事实上,JSP页面通常无须配置,也就不存在配置信息。因此,该对象更多地在Servlet中有效。 exception:java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page的isErrorPage属性为true时,该对象才可以使用。常用的方法有getMessage()和printStackTrace()等。 out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容,形成HTML页面。 page:代表该页面本身,通常没有太大用处。也就是Servlet中的this,其类型就是生成的Servlet类,能用page的地方就可用this。 pageContext:javax.servlet.jsp.PageContext的实例,该对象代表该JSP页面上下文,使用该对象可以访问页面中的共享数据。常用的方法有getServletContext()和getServletConfig()等。 request:javax.servlet.http:HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。常用的方法有getParameter(String paramName)、getParameterValues(String paramName)、setAttribute(String atttName,Object attrValue)、getAttribute(String attrName)和setCharacterEncoding(String env)等。 response:javax.servlet.http.HttpServletResponse的实例,代表服务器对客户端的响应。通常很少使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。而response对象常用于重定向,常用的方法有getOutputStream()、sendRedirect(java.lang.String location)等。 session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端浏览器与站点建立连接时,会话开始;当客户端关闭浏览器时,会话结束。常用的方法有:getAttribute(String attrName)、setAttribute(String attrName, Object attrValue)等。进入Tomcat的workCatalinalocalhostjspPrincipleorgapachejsp路径下,打开任意一个JSP页面对应生成的Servlet类文件,看到如下代码片段:public final class test_jsp extends org.apache.jasper.runtime.HttpJspBaseimplements org.apache.jasper.runtime.JspSourceDependent ./用于响应用户请求的方法public void _jspService(HttpServletRequest request, HttpServletResponse response)throws java.io.IOException, ServletException PageContext pageContext = null;HttpSession session = null;ServletContext application = null;ServletConfig config = null;/定义页面输出流JspWriter out = null;Object page = this;JspWriter _jspx_out = null;PageContext _jspx_page_context = null;try /设置响应格式response.setContentType(text/html; charset=gb2312);pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);jspx_page_context = pageContext;application = pageContext.getServletContext();config = pageContext.getServletConfig();session = pageContext.getSession();/初始化页面输出流out = pageContext.getOut();.几乎所有的JSP页面编译后Servlet类都有如上所示的结构,上面Servlet类的粗体字代码表明:reques、response两个对象是_jspService()方法的形参,当Tomcat调用该方法时会初始化这两个对象。而page、pageContext、application、config、session、out都是_jspService()方法的局部变量,由该方法完成初始化。通过上面代码不难发现JSP内置对象的实质,这些内置对象并没有任何神奇之处,它们要么是_jspService()方法的形参,要么是_jspService()方法的局部变量,所以我们直接调用这些对象,无须创建它们。当我们编写JSP页面时,一定不要仅停留在JSP页面本身来看问题,这样可能导致许多误解,导致我们无法理解JSP的运行方式。很多书籍上随意介绍这些对象,也是形成误解的原因之一。最后还要指出的是,因为上面8个内置对象要么是_jspService()方法的形参,要么是_jspService()方法的局部变量,所以JSP页面中只有JSP脚本才可以直接访问它们,JSP声明部分不能直接使用内置对象。细心的读者可能已经发现了:上面代码中并没有exception内置对象,这与前面介绍的正好相符:只有当页面的page指令的isErrorPage属性为true时,才可使用exception对象。也就是说:只有异常处理页面对应Servlet才会初始化exception对象。2.9.1 application对象在介绍application对象之前,先简单介绍一些Web服务器的实现原理。虽然绝大部分读者都不需要、甚至不曾想过自己开发Web服务器,但了解一些Web服务器的运行原理,对于更好地掌握JSP知识将有很大的帮助。虽然常把基于Web应用称为B/S(Browser/Server)架构的应用,但其实Web应用一样是C/S(Client/Server)结构的应用,只是这种应用的服务器是Web服务器,而客户端是浏览器。现在我们抛开Web应用直接看Web服务器和浏览器,对于大部分浏览器而言,它通常负责完成3件事情:* 向远程服务器发送请求。Adobe Systems 读取远程服务器返回的字符串数据。* 负责根据字符串数据渲染出一个丰富多彩的页面。实际上,浏览器是一个非常复杂的网络通信程序,它除了可以向服务器发送请求、读取网络数据之外,最大的技术难点在于将HTML文本渲染成页面,建立HTML页面的DOM模型,支持JavaScript脚本程序等。通常浏览器有Internet Explorer、FireFox、Opera等,至于其他如MyIE、傲游等浏览器可能只是对它们进行了简单的包装。Web服务器则负责接收客户端请求,每当接收到客户端连接请求之后,Web服务器应该使用单独的线程为该客户端提供服务:接收请求数据、送回响应数据。图2.17显示了Web服务器的运行机制。图2.17 Web服务器运行机制如图2.17所示的应用架构,总是先由客户端发送请求,服务器接收到请求后送回响应的数据,所以也将这种架构称做“请求/响应”架构。从如图2.17所示的机制来归纳,对于每个客户端而言,Web服务器大致需要完成如下几个步骤:* 启动单独的线程。Adobe Systems 使用IO流读取用户的请求数据。Adobe Systems 从请求数据中解析参数。* 处理用户请求。Adobe Systems 生成响应数据。* 使用IO流向客户端发送请求数据。在上面6个步骤中,第1、2和6步是通用的,可以由Web服务器来完成,但第3、4和5步则存在差异:因为不同请求里包含的请求参数不同,处理用户请求的方式也不同,所生成的响应自然也不同。那么Web服务器到底如何执行第3、4和5步呢?实际上,Web服务器会调用Servlet的_jspService()方法来完成第3、4和5步,当我们编写JSP页面时,页面里的静态内容、JSP脚本都会转换成_jspService()方法的执行代码,这些执行代码负责完成解析参数、处理请求、生成响应等业务功能,而Web服务器则负责完成多线程、网络通信等底层功能。Web服务器在执行了第3步解析到用户的请求参数之后,将需要通过这些请求参数来创建HttpServletRequest、HttpServletResponse等对象,作为调用_jspService()方法的参数,实际上一个Web服务器必须为Servlet API中绝大部分接口提供实现类。从上面介绍可以看出,Web应用里的JSP页面、Servlet等程序都将由Web服务器来调用,JSP、Servlet之间通常不会相互调用,这就产生了一个问题:JSP、Servlet之间如何交换数据?为了解决这个问题,几乎所有Web服务器(包括Java、ASP、PHP、Ruby等)都会提供4个类似Map的结构,分别是application、session、request、page,并允许JSP、Servlet将数据放入这4个类似Map的结构中,并允许从这4个Map结构中取出数据。这4个Map结构的区别是范围不同: application:对于整个Web应用有效,一旦JSP、Servlet将数据放入application中,该数据将可以被该应用下其他所有的JSP、Servlet访问。 session:仅对一次会话有效,一旦JSP、Servlet将数据放入session中,该数据将可以被本次会话的其他所有的JSP、Servlet访问。 request:仅对本次请求有效,一旦JSP、Servlet将数据放入request中,该数据将可以被该本次请求的其他JSP、Servlet访问。 page:仅对当前页面有效,一旦JSP、Servlet将数据放入page中,该数据只可以被当前页面的JSP脚本、声明部分访问。就像现实生活中有2个人,他们的钱需要相互交换,但他们2个人又不能相互接触,那么只能让A把钱存入银行,而B从银行去取钱。因此,我们可以把application、session、request和page理解为类似银行的角色。把数据放入application、session、request或page之后,就相当于扩大了该数据的生存范围,所以我们也认为application、session、request和page中的数据分别处于application、session、request和page范围之内。JSP中的application、session、request和pageContext 4个内置对象分别用于操作application、session、request和page范围中的数据。application对象代表Web应用本身,因此使用application来操作Web应用相关数据。application对象通常有如下两个作用: 在整个Web应用的多个JSP、Servlet之间共享数据。 访问Web应用的配置参数。1. 让多个JSP、Servlet共享数据application通过setAttribute(String attrName,Object value)方法将一个值设置成application的attrName属性,该属性的值对整个Web应用有效,因此该Web应用的每个JSP页面或Servlet都可以访问该属性,访问属性的方法为getAttribute(String attrName)。看下面的页面,该页面仅仅声明了一个整型变量,每次刷新该页面时,该变量值加1,然后将该变量的值放入application内。下面是页面的代码:程序清单:codes022.9jspObjectput-application.jspapplication测试上面页面的粗体字代码实现了每次刷新该页面时,变量i都先自加,并被设置为application的counter属性的值,即每次application中的counter属性值都会加1。再看下面的JSP页面,该页面可以直接访问到application的counter属性值。程序清单:codes022.9jspObjectget-application.jspapplication测试上面页面中粗体字代码直接输出application的counter属性值,虽然这个页面和put-application.jsp没有任何关系,但它一样可以访问到application的属性,因为application的属性对于整个Web应用的JSP、Servlet都是共享的。在浏览器的地址栏中访问第一个put-application.jsp页面,经多次刷新后,看到如图2.18所示的页面。图2.18 将变量值放入application中访问get-application.jsp页面,也可看到类似于图2.18所示的效果,因为get-application.jsp页面可以访问application的counter属性值。application不仅可以用于两个JSP页面之间共享数据,还可以用于Servlet和JSP之间共享数据。我们可以把application理解成一个Map对象,任何JSP、Servlet都可以把某个变量放入application中保存,并为之指定一个属性名;而该应用里的其他JSP、Servlet就可以根据该属性名来得到这个变量。下面的Servlet代码示范了如何在Servlet中访问application里的变量。程序清单:codes022.9jspObjectWEB-INFsrcleeGetApplication.javapublic class GetApplication extends HttpServletpublic void service(HttpServletRequest request,HttpServletResponse response)throws IOExceptionresponse.setContentType(text/html;charset=gb2312);PrintWriter out = response.getWriter();out.println();out.println(测试application);out.println(); ServletContext sc = getServletConfig().getServletContext();out.print(application中当前的counter值为:);out.println(sc.getAttribute(counter);out.println();由于在Servlet中并没有application内置对象,所以上面程序第一行粗体字代码显式获取了该Web应用的ServletContext实例,每个Web应用只有一个ServletContext实例,在JSP页面中可通过application内置对象访问该实例,而Servlet中则必须通过代码获取。程序第二行粗体字代码访问、输出了application中的counter变量。该Servlet类同样需要编译成class文件才可使用,实际上Servlet还需要部署,关于Servlet的用法请参看2.10节。编译Servlet时可能由于没有添加环境出现异常,如果安装了Java EE SDK,只需将Java EE SDK路径的javaee.jar文件添加到CLASSPATH环境变量中;如果没有安装Java EE SDK,可以将Tomcat的lib路径下的jsp-api.jar、servlet-api.jar两个文件添加到CLASSPATH环境变量中。将Servlet部署在Web应用中,在浏览器中访问Servlet,出现如图2.19所示的页面。图2.19 Servlet访问application变量最后要指出的是:虽然使用application(即ServletContext实例)可以方便多个JSP、Servlet共享数据,但不要仅为了JSP、Servlet共享数据就将数据放入application中!由于application代表整个Web应用,所以通常只应该把Web应用的状态数据放入application里。2. 获得Web应用配置参数application还有一个重要用处:可用于获得Web应用的配置参数。看如下JSP页面,该页面访问数据库,但访问数据库所使用的驱动、URL、用户名及密码都在web.xml中给出。程序清单:codes022.9jspObjectgetWebParam.jspapplication测试上面程序中粗体字代码使用application的getInitParameter(String paramName)来获取Web应用的配置参数,这些配置参数应该在web.xml文件中使用context-param元素配置,每个context-param元素配置一个参数,该元素下有如下两个子元素: param-name:配置Web参数名。 param-value:配置Web参数值。web.xml文件中使用context-param元素配置的参数对整个Web应用有效,所以也被称为Web应用的配置参数。与整个Web应用有关的数据,都应该通过application对象来操作。为了给Web应用配置参数,则应在web.xml文件中增加如下片段:程序清单:codes022.9jspObjectWEB-INFweb.xmldrivercom.mysql.jdbc.Driverurljdbc:mysql:/localhost:3306/javaeeuserrootpass32147在浏览器中浏览getWebParam.jsp页面时,可看到数据库连接、数据查询完全成功。可见,使用application可以访问Web应用的配置参数。通过这种方式,可以将一些配置信息放在web.xml文件中配置,避免使用硬编码方式写在代码中,从而更好地提高程序的移植性。2.9.2 config对象config对象代表当前JSP配置信息,但JSP页面通常无须配置,因此也就不存在配置信息。该对象在JSP页面中比较少用,但在Servlet中则用处相对较大,因为Servlet需要在web.xml文件中进行配置,可以指定配置参数。关于Servlet的使用将在2.10节介绍。看如下JSP页面代码,该JSP代码使用了config的一个方法getServletName()。程序清单:codes022.9jspObjectconfigTest.jsp测试config内置对象上面代码中粗体字代码输出了config的getServletName()方法的返回值,所有的JSP页面都有相同的名字:jsp,所以粗体字代码输出为jsp。实际上,我们也可以在web.xml文件中配置JSP(只是比较少用),这样就可以为JSP页面指定配置信息,并可为JSP页面另外设置一个URL。config对象是ServletConfig的实例,该接口用于获取配置参数的方法是getInitParameter(String paramName)。下面代码示范了如何在页面中使用config获取JSP配置参数。程序清单:codes022.9jspObjectconfigTest2.jsp测试config内置对象name配置参数的值:age配置参数的值:上面代码中两行粗体字代码输出了config的getInitParameter()方法返回值,它们分别获取name、age两个配置参数的值。配置JSP也是在web.xml文件中进行的,JSP被当成Servlet配置,为Servlet配置参数使用init-param元素,该元素可以接受param-name和param-value两个子元素,分别指定参数名和参数值。在web.xml文件中增加如下配置片段,即可将JSP页面配置在Web应用中。config/configTest2.jspnameyeekuage30config/config上面的配置文件片段中粗体字代码为该Servlet(其实是JSP)配置了2个参数:name和value。上面的配置片段把configTest2.jsp页面配置成名为config的Servlet,并将该Servlet映射到/config处,这就允许我们通过/config来访问该页面。在浏览器中访问/config看到如图2.20所示的界面。图2.20 输出JSP配置参数值从图2.20中可以看出,通过config可以访问到web.xml文件中的配置参数。实际上,我们也可以直接访问configTest2.jsp页面,在浏览器中访问该页面将看到如图2.21所示的界面。图2.21 直接访问JSP页面将不能访问配置参数对比图2.20和2.21不难看出,如果希望JSP页面可以获取web.xml配置文件中的配置信息,则必须通过为该JSP分配的路径来访问该页面,因为只有这样访问JSP页面才会让配置文件起作用。2.9.3 exception对象exception对象是Throwable的实例,代表JSP脚本中产生的错误和异常,是JSP页面异常机制的一部分。在JSP脚本中无须处理异常,即使该异常是checked异常。事实上,JSP脚本包含的所有可能出现的异常都可交给错误处理页面处理。看下面的异常处理结构:try文本框: 普通页面/代码处理段.catch (Exception exception)文本框: 异常处理页面/异常处理段.这是典型的异常捕捉处理块。在JSP页面中,普通的JSP脚本只执行第一个部分代码处理段,而异常处理页面负责第二个部分异常处理段。在异常处理段中,可以看到有个异常对象,该对象就是内置对象exception。exception对象仅在异常处理页面中才有效,通过前面的异常处理结构,读者可以非常清晰地看出这点。打开普通JSP页面所生成的Servlet类,将可以发现如下代码片段:public void _jspService(HttpServletRequest request, HttpServletResponse response)throws java.io.IOException, ServletException try /所有JSP脚本、静态HTML部分都会转换成此部分代码response.setContentType(text/html; charset=gb2312);.out.write(rn);out.write(rn); catch (Throwable t) ./处理该异常if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); finally /释放资源_jspxFactory.releasePageContext(_jspx_page_context);从上面代码的粗体字代码中可以看出,JSP脚本和静态HTML部分都将转换成_jspSerivice()方法里的执行性代码这就是JSP脚本无须处理异常的原因:因为这些脚本已经处于try块中。一旦try块捕捉到JSP脚本的异常,并且_jspx_page_context不为null,就会由该对象来处理该异常,如上面粗体字代码所示。_jspx_page_context对异常的处理也非常简单:如果该页面的page指令指定了errorPage属性,则将请求forward到errorPage属性指定的页面,否则使用系统页面来输出异常信息。由于只有JSP脚本、输出表达式才会生成_jspx_page_context方法里的代码,所以这两个部分的代码无须处理异常。但JSP的声明部分依然强制处理checked异常,JSP的异常处理机制对JSP声明不起作用。在JSP的异常处理机制中,一个异常处理页面可以处理多个JSP页面脚本部分的异常。异常处理页面通过page指令的errorPage属性确定。下面页面再次测试了JSP脚本的异常机制。程序清单:codes022.9jspObjectthrowEx.jspJSP脚本的异常机制上面页面的粗体字代码将抛出一个ArithmeticEception,则JSP异常机制将会转发到error.jsp页面,error.jsp页面代码如下:程序清单:codes022.9jspObjecterror.jsp异常处理页面异常类型是:异常信息是:上面页面page指令的isErrorPage属性被设为true,则可以通过exception对象来访问上一个页面所出现的异常。在浏览器中请求throwEx.jsp页面,将看到如图2.22所示的界面。图2.22 使用exeption对象打开error.jsp页面生成的Servlet类,在_jspService()方法中发现如下代码片段:public void _jspService(HttpServletRequest request, HttpServletResponse response)throws java.io.IOException, ServletException PageContext pageContext = null;HttpSession session = null;/初始化exception对象Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);if (exception != null) response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);.从上面代码片段的粗体字代码中可以看出,当JSP页面page指令的isErrorPage为true时,该页面就会提供exception内置对象。应将异常处理页面中page指令的isErrorPage属性设置为true。只有当isErrorPage属性设置为true时才可访问exception内置对象。2.9.4 out对象out对象代表一个页面输出流,通常用于在页面上输出变量值及常量。一般在使用输出表达式的地方,都可以使用out对象来达到同样效果。看下面的JSP页面使用out来执行输出。程序清单:codes022.9jspObjectoutTest.jspout测试%/遍历结果集while(rs.next()/输出表格行out.println();/输出表格列out.println();/输出结果集的第二列的值out.println(rs.getString(1);/关闭表格列out.println();/开始表格列out.println();/输出结果集的第三列的值out.println(rs.getString(2);/关闭表格列out.println();/关闭表格行out.println();%从Java的语法上看,上面的程序更容易理解,out是个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智能支付解决方案可行性研究报告及总结分析
- 2025年社区共享停车项目可行性研究报告及总结分析
- 2025年城市社区共享空间建设项目可行性研究报告及总结分析
- 2025年社交电商创业项目可行性研究报告及总结分析
- 2025年未来食品科技研发可行性研究报告及总结分析
- 2025年生鲜食品供应链管理系统可行性研究报告及总结分析
- 2025年气候变化应对智能预测系统可行性研究报告及总结分析
- 2025年绿色出行服务合同(交通)
- 2025年零食销售返点合同
- 2025年绿色餐饮服务体系建设可行性研究报告及总结分析
- 中国少数民族文化智慧树知到期末考试答案章节答案2024年云南大学
- 福建省烟草专卖局(公司)招聘考试真题2023
- 闽教版2023版3-6年级全8册英语单词表
- 光学指纹识别技术与仪器
- 高延性混凝土加固施工专项方案
- 中药学类专业大学生职业生涯规划书
- 茂名市恒兴养殖有限公司江湖镇龙梅生产基地建设项目环评报告
- 起重机维护保养记录表
- 2023年07月广西自然资源职业技术学院招考聘用笔试历年难易错点考题荟萃附带答案详解
- 2019电网通信网络运行班组标准化管理手册
- 年产1000吨山野菜加工生产线项目谋划书
评论
0/150
提交评论