一 . ServletConfig
1. Servlet1代码
@WebServlet(
urlPatterns = "servlet1",
initParams = {@WebInitParam(name = "keya", value = "valueA")}
)
public class Servlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig(); // 获取初始配置信息
// 根据参数名获取参数值
String keya = servletConfig.getInitParameter("keya");
System.out.println("keya:" + keya);
// 获取所有的初始参数的名字
// hasMoreElements 判断有没有下一个参数 如果有返回true 如果没有返回false
// nextElement 1.取出下一个元素 2.向下移动游标
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String pname = initParameterNames.nextElement();
System.out.println(pname + "=" + getInitParameter(pname));
}
}
}
2、配置初始化参数的两种方式
Servlet 初始化参数有 XML 配置(web.xml) 和 注解配置(@WebServlet) 两种主流方式,本质都是给 ServletConfig
传参。
方式 1:XML 配置(web.xml)
在 WEB-INF/web.xml 里,给 Servlet 加 <init-param>
标签:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>com.servlet.Servlet1</servlet-class>
<!--配置 servlet 的初始参数-->
<init-param>
<param-name>keya</param-name>
<param-value>valueA</param-value>
</init-param>
<init-param>
<param-name>keyb</param-name>
<param-value>valueb</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
方式 2:注解配置(@WebServlet)
用 @WebServlet
注解直接在 Servlet 类上配置,替代 web.xml:
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
@WebServlet(
// 访问路径
urlPatterns = "/servlet1",
// 初始化参数:@WebInitParam 可配多个
initParams = {
@WebInitParam(name = "keya", value = "valueA"),
@WebInitParam(name = "keyb", value = "valueB")
}
)
3、Servlet 读取参数的核心代码逻辑
不管用 XML 还是注解配置参数,ServletConfig
的用法完全一致。以下是代码拆解:
1. 基础用法:获取单个参数
通过 getServletConfig()
拿到 ServletConfig
对象,再用 getInitParameter("参数名")
取值:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1. 获取 ServletConfig 对象
ServletConfig config = getServletConfig();
// 2. 根据参数名取单个值(如 "keya")
String keyaValue = config.getInitParameter("keya");
System.out.println("keya: " + keyaValue);
}
2. 进阶用法:遍历所有参数
用 getInitParameterNames()
获取参数名枚举(Enumeration
),结合 hasMoreElements()
和 nextElement()
遍历:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletConfig config = getServletConfig();
// 1. 获取所有参数名的枚举
Enumeration<String> paramNames = config.getInitParameterNames();
// 2. 遍历枚举:hasMoreElements() 判断是否有下一个参数
while (paramNames.hasMoreElements()) {
// 3. nextElement() 取出参数名,再用 getInitParameter() 取值
String paramName = paramNames.nextElement();
String paramValue = config.getInitParameter(paramName);
System.out.println(paramName + " = " + paramValue);
}
}
枚举遍历逻辑:
hasMoreElements()
:类似于迭代器Iterator
的hasNext()
方法,判断是否还有未遍历的参数名。-
nextElement()
:类似next()
,取出当前参数名,并 “移动游标” 到下一个。
核心知识点 | 关键内容 |
---|---|
ServletConfig 作用 | 管理 Servlet 初始化参数,实现 “配置与代码解耦” |
配置参数的两种方式 | - XML:<init-param> 写在 web.xml- 注解: @WebServlet + @WebInitParam |
常用方法 | - getInitParameter("name") :读单个参数- getInitParameterNames() :遍历所有参数名 |
枚举遍历逻辑 |
|
二 . ServletContext
0.ServletContext是什么?
ServletContext对象又称呼为 上下文对象,或者叫 应用域对象
核心是 “全局共享”
容器会为每个app创建一个独立的唯一的ServletContext对象
ServletContext对象为所有的Servlet所共享
ServletContext可以为所有的Servlet提供初始配置参数
通过它可以:
- 让不同组件(Servlet、Filter 等)互通数据;
- 管理应用级资源和配置;
- 监听应用生命周期事件。
1. Servlet 初始化参数获取
在 Servlet 类(如 Servlet1
、Servlet2
)的 service
方法里
// 获取所有的初始参数的名字
// hasMoreElements 判断有没有下一个参数 如果有返回true 如果没有返回false
// nextElement 1.取出下一个元素 2.向下移动游标
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String pname = initParameterNames.nextElement();
System.out.println(pname + "=" + getInitParameter(pname));
}
- 作用:通过
ServletConfig
获取当前 Servlet 的初始化参数名枚举,遍历枚举拿到参数名,再用getInitParameter(pname)
(底层依赖ServletConfig
)获取对应参数值,实现 “逐个读取 Servlet 专属初始化参数” 的逻辑。 - 细节:
hasMoreElements
是枚举的 “是否还有元素” 判断,nextElement
既取当前元素,又移动枚举游标,保证循环能依次拿到所有参数名。
2. ServletContext 获取与作用
有多种获取 ServletContext
的方式:
ServletConfig servletConfig = getServletConfig();
// 获取ServletContext
ServletContext servletContext1 = servletConfig.getServletContext(); //实例化的对象
ServletContext servletContext2 = req.getServletContext();
ServletContext servletContext3 = getServletContext();
ServletContext application = getServletContext(); //常命名为 application
结合 GenericServlet
类的源码
public ServletContext getServletContext() {
return this.getServletConfig().getServletContext();
}
- 核心逻辑:不管是通过
ServletConfig
、HttpServletRequest
,还是直接调用getServletContext()
,最终都是从ServletConfig
里拿ServletContext
,保证一个 Web 应用里所有 Servlet 拿到的是同一个全局上下文对象(可通过servletContext1 == servletContext2
这类代码验证是否为同一对象 )。 - 作用:
ServletContext
用于获取整个 Web 应用全局参数(比如web.xml
里<context-param>
配置的参数 ),示例:String encoding = servletContext1.getInitParameter("encoding"); System.out.println("encoding:" + encoding); Enumeration<String> parameterNames = servletContext1.getInitParameterNames(); while (parameterNames.hasMoreElements()){ String pname = parameterNames.nextElement(); System.out.println(pname + "=" + servletContext1.getInitParameter(pname)); }
这里就是用ServletContext
读取全局参数,和 Servlet 自身初始化参数区分开,实现 “全局配置 + 局部配置” 的组合使用。
3. 代码结构与配置关联
web.xml
里的<context-param>
:属于 Web 应用全局参数,通过ServletContext
读取,作用范围是整个应用(所有 Servlet 都能拿到)。@WebServlet
或web.xml
里的<init-param>
:属于单个 Servlet 的初始化参数,通过ServletConfig
读取,作用范围仅限当前 Servlet 实例
比如 Servlet1
的注解配置:
@WebServlet(
urlPatterns = "servlet1",
initParams = {@WebInitParam(name = "keya", value = "valuea")}
)
Servlet相关API
// 获得一个指向项目部署位置下的某个文件/目录的磁盘真实路径的API
String path = servletContext.getRealPath("/upload");
System.out.println(path);
/ 获得项目部署的上下文路径 项目的访问路径
// 后续我们会学习在项目中使用相对和绝对路径找目标资源
// 获取项目的上下文路径 项目的访问路径
String contextPath = servletContext.getContextPath();
域对象
// 域对象API测试
Context1.setAttribute("key1", "value1");
Context1.setAttribute("key1", "value2");
System.out.println(Context1.getAttribute("key1")); // 输出:value2
String value1 = (String) Context1.getAttribute("key1");
System.out.println(value1); // 输出:value2
Context1.removeAttribute("key1");
System.out.println(Context1.getAttribute("key1"));
// 域对象API测试 属性覆盖机制 Context1.setAttribute("key1", "value1"); Context1.setAttribute("key1", "value2"); System.out.println(Context1.getAttribute("key1")); String value1 = (String) Context1.getAttribute("key1"); System.out.println(value1); Context1.removeAttribute("key1"); System.out.println(Context1.getAttribute("key1"));
removeAttribute
会彻底删除指定键的属性。
移除后再次获取该键的值将返回null
。