1、什么是ServletContext?
<1.>web容器启动时,它会为每个web应用程序创建一个对应的ServletContext对象,代表当前的web应用程序。可以将之理解为一个Servlet容器。每一个项目都会有一个ServletContext。类似于下面这个图:
<2.>如上图所示:一个ServletContext中包含多个Servlet,所以一个web应用中的Servlet共享一个ServletContext对象,Servlet对象之间可以通过ServletContext进行通讯,ServletContext对象也通常被称之Context域对象。
2、Servlet如何通过ServletContext来通信?
其实并没有通信这一说法,真正的说法其实是,如何都去获得一个通用的值,我们看一段代码:
<!--web.xml中全局容器变量的设置:-->
<!-- 全局(ServletContext)容器参数:公用的一些属性,需要用context-param标签来封装 -->
<context-param>
<param-name>Context-name</param-name>
<param-value>contextTest</param-value>
</context-param>
各个Servlet可以通过init方法来获得这些全局参数:
package one;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
* Servlet implementation class ServletContextDemo01
*/
@WebServlet("/ServletContextDemo01")
public class ServletContextDemo01 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init(ServletConfig config) throws ServletException {
/*获得全局容器参数的方法:
1、获得ServletContext对象
2、获得的对象可以用getgetInitParameter方法来获得键值对对应的值
*/
ServletContext sc = config.getServletContext();
String contextValue = sc.getInitParameter("Context-name");
System.out.println(contextValue);
}
}
3、ServletContext的全局属性设置
通过一段代码来看:我们创建两个Servlet,每个Servlet我们写一段逻辑来统计点击的次数,我们这两个Servlet的代码是一样的,我们最后通过测试来看两者的参数是否通用。
package one;
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;
/**
* Servlet implementation class ServletContextDemo02
*/
@WebServlet("/ServletContextDemo02")
public class ServletContextDemo02 extends HttpServlet {
private static final long serialVersionUID = 1L;
/*
* 作用:统计访问次数
* pvcount是一个全局参数,在demo02中设置逻辑,pvcount为点击的次数
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得ServletContext对象
ServletContext sc = getServletContext();
//获得全局属性值,并进行分析设置
Integer pvcount = (Integer)sc.getAttribute("pvcount");
if(pvcount==null){
sc.setAttribute("pvcount", 1);
}else{
sc.setAttribute("pvcount", ++pvcount);
}
String result = "<font color='red' size='20'>被点击了"+pvcount+"次</font>";
response.getOutputStream().write(result.getBytes());
}
}
package one;
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;
/**
* Servlet implementation class ServletContextDemo03
*/
@WebServlet("/ServletContextDemo03")
public class ServletContextDemo03 extends HttpServlet {
private static final long serialVersionUID = 1L;
/*
*
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得ServletContext对象
ServletContext sc = getServletContext();
//获得全局属性值,并进行分析设置
Integer pvcount = (Integer)sc.getAttribute("pvcount");
if(pvcount==null){
sc.setAttribute("pvcount", 1);
}else{
sc.setAttribute("pvcount", ++pvcount);
}
String result = "<font color='red' size='20'>被点击了"+pvcount+"次</font>";
response.getOutputStream().write(result.getBytes());
}
}
看看测试的结果:我们访问demo02,点击刷新两次:
那么我们思考一下,如果访问demo03,再次点击2次,结果应该是4,还是2?
充分证明了我们的思路,除了在web.xml文件中设置全局参数,也可以在代码中直接设置,来使用。
3、通过ServletContext来获取工程的根目录
我们在实际的开发中要用到一些文件或者文件夹中的内容,这时候我们需要去获得项目的根目录的位置,如下可用ServletContext来获得根目录:
@Override
public void init(ServletConfig config) throws ServletException {
ServletContext sc = config.getServletContext();
String path = sc.getRealPath("/");
System.out.println(path);
}
输出结果:
D:\apache-tomcat-7.0.81\webapps\ServletDemo\
举一个例子,我们都知道tomcat下的工程目录结构是:webapps/项目的名字,在此目录下还有WEB-INF和MATA-INF两个文件夹,平时用的资源会放到WEB-INF目录下,我们假如有一个test.properties类型的文件,该后缀文件代表了是个配置文件,(不了解的请自行百度),我们可以去读取该文件:
package one;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HttpServletDemo extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
ServletContext sc = config.getServletContext();
String path = sc.getRealPath("/");
System.out.println(path);
//读取文件内容,下面的第一个/代表项目的根目录
InputStream is = sc.getResourceAsStream("/WEB-INF/test.properties");
Properties pro = new Properties();
try {
pro.load(is);
System.out.println(pro.getProperty("key"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet方法被调用");
resp.getOutputStream().write("doGet方法被调用".getBytes());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}