
3.8 Servlet上下文
服务器上的每个Web应用都会有一个背景环境对象,称为上下文,Web应用中的所有资源包括Servlet、JSP、JavaBean和静态HTML页面等共享此上下文对象,因此上下文对象提供了一个同一Web应用内的不同资源间共享信息的场所。Javax.Servlet. ServletContext接口提供正在运行的Servlet所处的Web应用程序的上下文对象的视图,可以通过getServletContext方法得到该Servlet运行的上下文对象。在创建Web应用程序时,通过Servlet上下文可以实现以下功能:
(1)访问Web应用程序资源。ServletContext可以通过getResource和getResourceAsStream方法访问Web应用程序内的静态资源文件。
(2)在Servlet上下文属性中保存Web应用程序信息。上下文对象可以用来存储Java对象,通过字符串值的key来识别对象,这些属性对整个Web应用程序都是全局的,Servlet可以通过getAttribute、getAttributeNames、removeAttribute和setAttribute方法进行操作。
(3)获取应用初始化参数信息。可以调用ServletContext的getInitParameterNames方法返回一个初始化参数的枚举对象(java.util.Enumeration),或直接指定一个参数名来得到特定的参数值,如ServletContext.getInitParameter(String name)。
注意:这里的初始化参数指的是整个Web应用的初始化参数,而不是针对哪个具体Web组件的。例如,开发人员可以将Web应用的运行模式设置为应用的初始化参数。在初始化参数修改后,必须重新启动Web应用才会生效。
(4)提供日志支持。可以简单地通过调用ServletContext.log(String msg)或ServletContext.log(String msg, Throwable throwable)方法向底层的Servlet日志记录写入日志信息;ServletContext.log(String msg, Throwable throwable)方法还可写入异常信息和throwable的跟踪栈。
ServletContext对此Web应用的任何客户端请求在任何时间都有效。要访问ServletContext对象,只要调用getServletContext()就可以了。
下面通过程序演示两个Servlet组件间如何通过上下文进行协同工作。其中AdminTemperatureServlet用来更新当前温度信息,ShowTemperatureServlet仅用来显示当前温度信息,两个Servlet间通过上下文中的属性来传递信息,实现温度信息实时更新与发布。
首先创建更新温度信息的AdminTemperatureServlet。它包含一个名为Temperature初始化参数,其值为8。代码如程序3-27所示。
程序3-27:AdminTemperatureServlet.java
package com.servlet; … @WebServlet(name="AdminTemperatureServlet", urlPatterns={ "/adminTempera ture" } , initParams ={ @WebInitParam(name = "Temperature", value ="8")}) public class AdminTemperatureServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=gb2312"); PrintWriter out = response.getWriter(); String Temperature=(String)getServletContext().getAttribute ("Temperature"); if(Temperature==null){ //获取初始化参数 Temperature=(String)getInitParameter("Temperature"); //放入应用上下文 getServletContext().setAttribute("Temperature", Temperature); } out.println("<HTML><HEAD><TITLE>气温更新 " + "</TITLE></HEAD>"); out.println("<BODY><TABLE border=\"0\" width=\"100%\"><tr>"); out.println("<td align=\"left\" valign=\"bottom\">"); out.println("<H1>当前气温</H1></td></tr></TABLE>"); out.print("<FORM ACTION=\""); out.println(response.encodeURL("adminTemperature")); out.println("\" METHOD=\"POST\">"); out.println("当前气温(摄氏度)"); out.println("<INPUT TYPE=\"text\" NAME=\"temperature\" " + "VALUE="+Temperature+">"); out.println("<INPUT TYPE=\"Submit\" NAME=\"btn_submit\" " + "VALUE=\"更新\">"); out.println("</FORM></BODY></HTML>"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=gb2312"); PrintWriter out = response.getWriter(); String Temperature=request.getParameter("temperature"); //将更新后的气温信息放入上下文 getServletContext().setAttribute("Temperature", Temperature); out.println("<HTML><HEAD><TITLE>气温更新 " + "</TITLE></HEAD>"); out.println("<BODY>"); out.println("当前气温:"+Temperature+"摄氏度"); out.println("</BODY></HTML>"); } … }
下面生成显示气温信息的ShowTemperatureServlet,代码如程序3-28所示。
程序3-28:ShowTemperatureServlet.java
package com.servlet; … @WebServlet(name=" ShowTemperatureServlet ", urlPatterns={"/ showTemperature "}) public class ShowTemperatureServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=gb2312"); PrintWriter out = response.getWriter(); String Temperature=(String)getServletContext().getAttribute ("Temperature"); if(Temperature==null){Temperature=new String("0"); } String oldTemperature=(String)request.getSession().getAttribute ("OldTemperature"); out.println("<HTML><HEAD><TITLE>气温信息显示 " + "</TITLE></HEAD>"); out.println("<BODY>"); out.println("当前最新气温:"+Temperature+"摄氏度"); if(oldTemperature! =null){ out.println("<BR>"); out.println("更新当前气温:"+oldTemperature+"摄氏度"); } out.println("</BODY></HTML>"); //更新会话中的气温信息 request.getSession().setAttribute("OldTemperature", Temperature); } … }
程序说明:AdminTemperatureServlet的doGet方法首先调用getServletContext方法获取应用的上下文对象ServletContext,然后调用ServletContext对象的getAttribute方法获取存储在上下文中的Temperature属性信息进行显示。如果是第一次调用,ServletContext中尚不存在Temperature属性对象,则调用getInitParameter方法获取存储在初始化参数中的气温信息并调用ServletContext的setAttribute方法将属性添加到上下文对象的Temperature属性对象中。ShowTemperatureServlet采用同样的方法获取上下文中的属性信息进行显示。
重新发布Web应用并启动浏览器,在地址栏中输入http://localhost:8080/Chapter3/adminTemperature,将得到如图3-32所示的结果,此时显示的为从Servlet初始化参数中获取的气温信息。将文本框中的气温数据更改为8并单击“更新”按钮提交。打开一个新的浏览器对话框,在地址栏中输入http://localhost:8080/Chapter3/showTemperature,将得到如图3-33所示的结果,此时显示的为从上下文对象获取的气温信息,可以看到气温信息已经更新了。重新进入如图3-32所示的页面来不断更新气温信息,然后重新刷新显示如图3-33所示的页面,可以看到,通过上下文,两个Servlet组件之间的信息交换变得很方便。

图3-32 气温更新页面

图3-33 气温显示页面