基本概念
- Web容器在启动时,会为每个Web应用程序都创建一个对应的ServletContext对象,它代表当前Web应用。
- ServletContext(javax.servlet.http.ServletContext )存储了整个Web应用运行的上下文信息,即Web应用的全局信息,并且这些信息可以被不同的Servlet共享。
- ServletConfig对象中维护了对ServletContext对象的引用,Tomcat创建Servlet对象后,在init方法中将ServletContext通过ServletConfig传递给当前的Servlet。
- 多个Servlet共享同一个ServletContext,ServletContext对象一直存活到整个Web应用停止。
- Servlet可以通过this.getServletContext() 来获取当前Web应用的ServletContext。通过ServletContext可以实现如下功能:
- 获取Web应用初始化参数:getInitParamNames(), getInitParamValue(String name)
- Servlet之间信息共享:getRequestDispatcher("/XX/XX") 实现信息的转发
- 读取资源文件 :根据ServletContext获取上下文的工作根目录,根据根目录下资源的路径映射此资源在硬盘的绝对路径,再根据getResourceAsStream或者getRealPath获取硬盘绝对路径下的文件流。
- 除了上述常用功能,Servlet还能实现对Listner/Filter/Session/Cookie的信息获取和配置,获取MimeType,URL下所有资源等等功能....
ServletContext 读取资源文件
- ServletContext中存的参数信息可以被所有Servlet共享,实际开发中常常把数据库,编码信息等所有Servlet都需要的参数化信息存储在ServletContext的配置中供Servlet调用:
- 配置web.xml中的ServletContext参数
- 在Servlet中通过获取ServletContext调用参数
示例:配置ServletContext参数
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <context-param> <param-name>firstContextParaName</param-name> <param-value>firstContextParaValue</param-value> </context-param> <servlet> <servlet-name>FirstServletContext</servlet-name> <servlet-class>servletContext.FirstServletContext</servlet-class> <init-param> <param-name>servletConfigName</param-name> <param-value>servletConfigValue</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>FirstServletContext</servlet-name> <url-pattern>/FirstServletContext</url-pattern> </servlet-mapping> </web-app>
示例:Servlet中获取Context参数
/** * 获取系统初始化参数web.xml里的context-param */ public void getAllInitialParams() { Enumeration<String> enums = this.getServletContext().getInitParameterNames(); String initParam; while (enums.hasMoreElements()) { initParam = enums.nextElement(); System.out.println("initParam names: " + initParam + " initParam value: " + this.getServletContext().getInitParameter(initParam)); } }
ServletContext 传递参数
ServletContext又被称为Context域对象,可以在此对象中存储参数,但通常不建议这么做,因为可能会有线程安全问题。使用ServletContext传递参数,采用以下几步:
- 在ServletA中设置参数(是attribute,不是initParam),servletContext().setAttribute("key","value");
- 在ServletB中获取参数(注意A必须运行在B前面),servletContext().getAttribute("key");
/** * ServletContext 对应Context域对象,可以在域对象中存储参数,servletContext.setAttribute("key","value"); * 普通变量的转发非常不赞同用Context,因为Context是全局的,在多线程条件下会导致变量的问题. * */ public class FirstServletContexForParasTransfer extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{ this.getServletContext().setAttribute("GenerateContextAttrsByServlet", "testContextServletAttrTransfer"); //设置Context域参数以后转发请求到另一个Servlet,另一个Servlet可以获取刚刚设置的参数;如果直接调用另一个Servlet,由于没有设置参数,取值结果会变为null this.getServletContext().getRequestDispatcher("/FirstServletContexForParasTransferReceiver").forward(request, response);; } }
public class FirstServletContexForParasTransferReceiver extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){ System.out.println("get a attribute from SevletContext: "+this.getServletContext().getAttribute("GenerateContextAttrsByServlet")); } }