Java EE 程序设计
上QQ阅读APP看书,第一时间看更新

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 气温显示页面