ServletContext接口详解
Servlet 容器启动时,会为每个 Web 应用(webapps 下的每个目录都是一个 Web 应用)创建一个唯一的 ServletContext 对象,该对象一般被称为“Servlet 上下文”。
ServletContext 对象的生命周期从 Servlet 容器启动时开始,到容器关闭或应用被卸载时结束。
Web 应用中的所有 Servlet 共享同一个 ServletContext 对象,不同 Servlet 之间可以通过 ServletContext 对象实现数据通讯,因此 ServletContext 对象也被称为 Context 域对象。
注意:以上最后两种方法了解即可,后面我们会详细讲解。
ServletContext 的应用主要有以下 3 个:
1) 设置上下文初始化参数
2) 调用接口中方法获取初始化参数
与 Servlet 的初始化参数不同,应用中的所有 Servlet 都共享同一个上下文初始化参数。在 Web 应用的整个生命周期中,上下文初始化参数会一直存在,并且可以随时被任意一个 Servlet 访问。
在 web.xml 文件中配置上下文初始化参数,代码如下所示。
下表列举了 ServletContext 接口中用于获取上下文初始化参数的相关方法。
启动 Tomcat 服务器,在地址栏输入“http://localhost:8080/servletDemo/ReadContextServlet”,访问 ReadContextServlet,结果如下图。
在 servletDemo 的 net.biancheng.www 包下,创建一个名称为 CountServlet 的 Servlet 类,代码如下。
然后再创建一个名称为 ShowServlet 的 Servlet 类,代码如下。
重启 Tomcat 浏览器,在地址栏输入“http://localhost:8080/servletDemo/CountServlet”,多次访问 CountServlet 次,结果如下图。
然后再输入“http://localhost:8080/servletDemo/ShowServlet”,访问 ShowServlet,结果如下图。
注:上表中参数 path 代表资源文件的虚拟路径,它以正斜线
在 servletDemo 的 src 目录中,创建一个名称为 db.properties 的文件,文件中输入如下所示的配置信息。
在 net.biancheng.www 包中,创建一个名称为 ReadServlet 的 Servlet 类,代码如下所示。
启动 Tomcat 服务器,在地址栏中输入“http://localhost:8080/servletDemo/ReadServlet”,访问 ReadServlet,结果如下图。
ServletContext 对象的生命周期从 Servlet 容器启动时开始,到容器关闭或应用被卸载时结束。
Web 应用中的所有 Servlet 共享同一个 ServletContext 对象,不同 Servlet 之间可以通过 ServletContext 对象实现数据通讯,因此 ServletContext 对象也被称为 Context 域对象。
域对象是服务器在内存上创建的存储空间,该空间用于不同动态资源(例如 Servlet、JSP)之间传递与共享数据。
获得 ServletContext 对象
获得 ServletContext 对象有以下 4 种方式:1. 通过 GenericServlet 提供的 getServletContext() 方法
//通过 GenericServlet的getServletContext方法获取ServletContext对象 ServletContext servletContext = this.getServletContext();
2. 通过 ServletConfig 提供的 getServletContext() 方法
//通过 ServletConfig的 getServletContext方法获取ServletContext对象 ServletContext servletContext = this.getServletConfig().getServletContext();
3. 通过 HttpSession 提供的 getServletContext() 方法
//通过 HttpSession的 getServletContext方法获取ServletContext对象 ServletContext servletContext = req.getSession().getServletContext();
4. 通过 HttpServletRequest 提供的 getServletContext() 方法
//通过 HttpServletRequest的 getServletContext方法获取ServletContext对象 ServletContext servletContext = req.getServletContext();
注意:以上最后两种方法了解即可,后面我们会详细讲解。
ServletContext 的应用
javax.servlet 包提供了一个 ServletContext 接口,该接口定义了一组方法,Servlet 可以使用这些方法与容器进行通信。ServletContext 的应用主要有以下 3 个:
- 获取上下文初始化参数
- 实现 Servlet 之间的数据通讯
- 读取 Web 应用下的资源文件
1. 获取上下文初始化参数
使用 ServletContext 对象获取 Web 应用的上下文初始化参数,分为 2 步:1) 设置上下文初始化参数
2) 调用接口中方法获取初始化参数
1) 设置上下文初始化参数
通过 web.xml 中的 <context-param> 元素可以为 Web 应用设置一些全局的初始化参数,这些参数被称为上下文初始化参数。与 Servlet 的初始化参数不同,应用中的所有 Servlet 都共享同一个上下文初始化参数。在 Web 应用的整个生命周期中,上下文初始化参数会一直存在,并且可以随时被任意一个 Servlet 访问。
在 web.xml 文件中配置上下文初始化参数,代码如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0" metadata-complete="false">
<!--设置全局初始化参数 -->
<context-param>
<param-name>name</param-name>
<param-value>编程帮</param-value>
</context-param>
<context-param>
<param-name>url</param-name>
<param-value>www.biancheng.net</param-value>
</context-param>
</web-app>
对以上标签说明如下:
- <context-param> 元素用来声明上下文初始化参数,必须在根元素 <web-app> 内使用。
- <param-name> 子元素表示参数名,参数名在整个 Web 应用中必须是唯一的。
- <param-value> 子元素表示参数值。
2) 调用接口中方法获取初始化参数
Servlet 容器启动时,会为容器内每个 Web 应用创建一个 ServletContext 对象,并将 <context-param> 元素中的上下文初始化参数以键值对的形式存入该对象中,因此我们可以通过 ServletContext 的相关方法获取到这些初始化参数。下表列举了 ServletContext 接口中用于获取上下文初始化参数的相关方法。
| 返回值类型 | 方法 | 描述 |
|---|---|---|
| String | getInitParameter(String name) | 根据初始化参数名 name,返回对应的初始化参数值。 |
| Enumeration<String> | getInitParameterNames() | 返回 Web 应用所有上下文初始化参数名的枚举集合,如果该 Web 应用没有上下文初始化参数,则返回一个空的枚举集合。 |
例 1
以 servletDemo 为例,在 net.biancheng.www 包下创建一个名称为 ReadContextServlet 的类,代码如下。
package net.biancheng.www;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ReadContextServlet")
public class ReadContextServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
// 调用httpServlet父类GenericServlet的getServletContext方法获取ServletContext对象
ServletContext context = super.getServletContext();
// 返回 context 上下文初始化参数的名称
Enumeration<String> initParameterNames = context.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
// 获取初始化参数名称
String initParamName = initParameterNames.nextElement();
// 获取相应的初始参数的值
String initParamValue = context.getInitParameter(initParamName);
// 向页面输出
writer.write(initParamName + " : " + initParamValue + "<br/>");
}
// 关闭流
writer.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
启动 Tomcat 服务器,在地址栏输入“http://localhost:8080/servletDemo/ReadContextServlet”,访问 ReadContextServlet,结果如下图。

2. 实现数据通讯
在 Servlet 中,调用 ServletContext 接口的 setAttribute() 方法可以创建一些属性,这些属性被存放在 ServletContext 对象中。应用中所有 Servlet 都可以对这些属性进行访问和操作,通过它们可以实现应用内不同 Servlet 之间的数据通讯。数据通讯的相关方法
下表列举了 ServletContext 接口实现数据通讯的相关方法。| 返回值类型 | 方法 | 描述 |
|---|---|---|
| void | setAttribute(String name, Object object) |
把一个 Java 对象与一个属性名绑定,并将它作为一个属性存放到 ServletContext 中。 参数 name 为属性名,参数 object 为属性值。 |
| void | removeAttribute(String name) | 从 ServletContext 中移除属性名为 name 的属性。 |
| Object | getAttribute(String name) | 根据指定的属性名 name,返回 ServletContext 中对应的属性值。 |
ServletContext 属性与上下文初始化参数对比
虽然 ServletContext 的属性与上下文初始化参数都是存放在 ServletContext 对象中,但它们是不同的。| 不同点 | ServletContext 的属性 | 上下文初始化参数 |
|---|---|---|
| 创建方式 | ServletContext 的属性通过调用 ServletContext 接口的 setAttribute() 方法创建 | 上下文初始化参数通过 web.xml 使用 <context-param> 元素配置 |
| 可进行的操作 | ServletContext 的属性可以通过 ServletContext 接口的方法进行读取、新增、修改、移除等操作 | 上下文初始化参数在容器启动后只能被读取,不能进行新增、修改和移除操作 |
| 生命周期 | ServletContext 中属性的生命周期从创建开始,到该属性被移除(remove)或者容器关闭结束 | 上下文初始化参数的生命周期,从容器启动开始,到 Web 应用被卸载或容器关闭结束 |
| 作用 | 使用 ServletContext 中的属性可以实现 Servlet 之间的数据通讯 | 使用上下文初始化参数无法实现数据通讯 |
例 2
我们通过编写一个统计页面访问量的案例,来演示如何通过 ServletContext 对象实现数据通讯。在 servletDemo 的 net.biancheng.www 包下,创建一个名称为 CountServlet 的 Servlet 类,代码如下。
package net.biancheng.www;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author 编程帮 www.biancheng.net
* 使用ServletContext 统计访问次数
*
*/
@WebServlet("/CountServlet")
public class CountServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
// 获取ServletContext对象
ServletContext context = getServletContext();
// 初始化时,向ServletContext中设置count属性,初始值为0
context.setAttribute("count", 0);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 调用httpServlet父类GenericServlet的getServletContext方法获取ServletContext对象
ServletContext context = super.getServletContext();
// 获取count的值,自增
Integer count = (Integer) context.getAttribute("count");
// 存入到域对象中
context.setAttribute("count", ++count);
// 向页面输出内容
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h3>编程帮 www.biancheng.net 欢迎您</h3>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
然后再创建一个名称为 ShowServlet 的 Servlet 类,代码如下。
package net.biancheng.www;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author 编程帮 www.biancheng.net
* 使用ServletContext展示网站的访问次数
*
*/
@WebServlet("/ShowServlet")
public class ShowServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取ServletContext中存放的count属性(即页面的访问次数)
Integer count = (Integer) getServletContext().getAttribute("count");
// 向页面输出
response.setContentType("text/html;charset=UTF-8");
// 若CountServlet已被访问
if (count != null) {
response.getWriter().write("<h3>该网站一共被访问了" + count + "次</h3>");
} else {
// 若CountServlet未被访问,提示先访问CountServlet
response.getWriter().write("<h3>请先访问 CountServlet</h3>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
重启 Tomcat 浏览器,在地址栏输入“http://localhost:8080/servletDemo/CountServlet”,多次访问 CountServlet 次,结果如下图。

然后再输入“http://localhost:8080/servletDemo/ShowServlet”,访问 ShowServlet,结果如下图。

3. 读取 Web 应用下的资源文件
在实际开发中,有时会需要读取 Web 应用中的一些资源文件,如配置文件和日志文件等。为此,ServletContext 接口定义了一些读取 Web 资源的方法 ,如下表。| 返回值类型 | 方法 | 方法描述 |
|---|---|---|
| Set | getResourcePaths(String path) | 返回一个 Set 集合,该集合中包含资源目录中的子目录和文件的名称。 |
| String | getRealPath(String path) | 返回资源文件的真实路径(文件的绝对路径)。 |
| URL | getResource(String path) | 返回映射到资源文件的 URL 对象。 |
| InputStream | getResourceAsStream(String path) | 返回映射到资源文件的 InputStream 输入流对象。 |
注:上表中参数 path 代表资源文件的虚拟路径,它以正斜线
/开始,/ 表示当前 Web 应用的根目录。
例 3
下面我们通过一个例子演示如何使用 ServletContext 对象读取资源文件。在 servletDemo 的 src 目录中,创建一个名称为 db.properties 的文件,文件中输入如下所示的配置信息。
name=编程帮 url=www.biancheng.net desc=编程帮,欢迎你
在 net.biancheng.www 包中,创建一个名称为 ReadServlet 的 Servlet 类,代码如下所示。
package net.biancheng.www;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author 编程帮 www.biancheng.net
* 使用ServletContext肚读取资源文件
*
*/
@WebServlet("/ReadServlet")
public class ReadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
// 获取相对路径中的输入流对象
InputStream ins = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
// 获取输入流
Properties pro = new Properties();
// 加载
pro.load(ins);
// 获取文件中的内容
String name = pro.getProperty("name");
String url = pro.getProperty("url");
String desc = pro.getProperty("desc");
writer.write("用户名:" + name + "<br/>" + "地址:" + url + "<br/>" + "描述:" + desc + "<br/>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
启动 Tomcat 服务器,在地址栏中输入“http://localhost:8080/servletDemo/ReadServlet”,访问 ReadServlet,结果如下图。

ICP备案:
公安联网备案: