什么是ServletContext:
- ServletContext是一个接口,它表示Servlet上下文对象
- 一个Web工程,只有一个ServletContext对象实例
- Servlet对象就是一个域对象
- ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁
域对象:可以像Map一样存取数据的对象,叫域对象
这里的域指的是存取数据的操作范围(整个Web工程)
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
ServletContext类的四个作用:
- 获取web.xml中配置的上下文参数context-param
- 获取当前的工作路径,格式:/工作路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map一样存取数据
获取web.xml中配置的上下文参数context-param:
首先配置web.xml,向其中添加以下内容:
<!-- Context-param是上下文参数(它属于整个web工程,只要是在这个web工程中的,像Servlet 程序、Filter 过滤器、Listener 监听器,都可以得到这些参数) -->
<!-- context-param根据需要,可以配置多组 -->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
ContextServlet.java中的doGet方法:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取web.xml中配置的上下文参数context-param
ServletContext context = getServletConfig().getServletContext(); //首先,通过ServletConfig获取到ServletContext对象
String username = context.getInitParameter("username");
System.out.println("context-param参数的username的值是:"+username);
String password = context.getInitParameter("password");
System.out.println("context-param参数的password的值是:"+password);
}
然后启动,访问:
http://localhost:8080/06_servlet1_war_exploded/contextServlet
运行结果:
注意:
通过使用这种方法,不可以得到init-param中的内容,
init-param只能是ServletConfig获取的,
context-param只能是ServletContext对象获取的。
获取当前的工作路径,格式:/工作路径:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 2. 获取当前的工作路径,格式:/工作路径
System.out.println("当前工程路径:" + context.getContextPath());
}
运行结果:
得到的结果就是:
获取工程部署后在服务器硬盘上的绝对路径:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 3. 获取工程部署后在服务器硬盘上的绝对路径
/*
/ 斜杠被服务器解析地址为:http://ip:port/工程名/
*/
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
}
运行结果:
访问此路径:(这个与我们模块中的web目录有着对应关系,下文会有提及)
让我们重启:
得到一个路径:
C:\Users\Point\.IntelliJIdea2019.3\system\tomcat\Tomcat_9_0_37_Javaweb
这个就是IDEA整合Tomcat之后,Tomcat被拷贝的一些副本内容。
访问此路径:
可以找到一个06_servlet1_war_exploded.xml配置文件:
前面的这个06_servlet1_war_exploded就是我们写的工程的工程路径,对应我们写的模块中的web目录(见上文:获取工程部署后在服务器硬盘上的绝对路径)。
web当成一个工程复制过去改名字变成了:06_servlet1_war_exploded
WEB-INF中的classes文件夹中会有一些src中编译生成的字节码。
总结一下:
/ 斜杠被服务器解析地址为:http://ip:port/工程名/
这个工程名,对应到磁盘上的C:\Users\Point\IdeaProjects\Javaweb\out\artifacts\06_servlet1_war_exploded\
磁盘上的这个位置,与IDEA中的web目录相对应,
也就是映射到IDEA代码中的WEB目录
由此,我们也可以得到web目录中的文件的绝对路径:
部署一下文件和图片:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下css目录的绝对路径是:" + context.getRealPath("/css"));
System.out.println("工程下imgs目录的1.jpg绝对路径是:" + context.getRealPath("/css/1.jpg"));
}
像Map一样存取数据:
这里写一种更简单的调用ServletContext对象的方法:
直接调用getServletContext方法:
ServletContext context = getServletContext();
getServletContext方法是在GenericServlet中创建的:
GenericServlet中先调用ServletConfig对象再调用的ServletContext
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象方法一:getServletConfig().getServletContext();
//获取ServletContext对象方法二:直接调用getServletContext()
ServletContext context = getServletContext();
System.out.println("保存之前:ServletContext1 中获取数据域key1的值是:" + context.getAttribute("key1"));
context.setAttribute("key1","value1");
System.out.println("ServletContext1 中获取数据域key1的值是:" + context.getAttribute("key1"));
}
创建一个ServletContext2:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println("ServletContext2 中获取数据域key1的值是:" + context.getAttribute("key1"));
}
- 先访问contextServlet1,再访问contextServlet1一次:
-
重新部署(Redeploy),再访问一次contextServlet1:
-
重新启动服务器(Restart server),再访问一次contextServlet1:
- 访问contextServlet2:
可见:
-
ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁!
-
存取数据的操作范围(整个Web工程)
部署(Redeploy):
它会先把原来的工程停了,然后再把工程整个启动,也就是说,服务器不用重启,工程是重启的。
如果是重新启动服务器(Restart server):
原先ServletContext的数据就不在了,需要先通过ServletContext context = getServletContext()
获取到,才能使前面的保存之前:ServletContext1 中获取数据域key1的值
拿到数据。
一个Web工程,只有一个ServletContext对象实例 的测试:
访问contextServlet1和contextServlet2,得到的context对象的地址都是一样的: