说起ServletContext,一些人会产生误解,以为一个servlet对应一个ServletContext。其实不是这样的,事实是一个web应用对应一个ServletContext,所以ServletContext的作用范围是整个应用,明确这点很重要,这是基础中的基础。
我曾经想,为什么不起名叫WebContext或者ApplicationContext或者WebApplicationContext?这样见名知意多好。后来我想这也可能是有历史原因的:最初的客户端-服务端的架构模型非常简单,服务端运行着一些servlet用来处理客户端的请求。那个时候服务器很轻量级,运行一个应用,应用就由一堆servlet组成。所以这样简单的服务器也被称作servlet容器,主要作用就是运行servlet的。那么提供给应用的上下文就叫做ServletContext。(这个纯属个人意淫^_^,不对勿喷)
一个web应用对应一个ServletContext实例,这个实例是应用部署启动后,servlet容器为应用创建的。ServletContext实例包含了所有servlet共享的资源信息。通过提供一组方法给servlet使用,用来和servlet容器通讯,比如获取文件的MIME类型、分发请求、记录日志等。
这里需要注意一点,如果你的应用是分布式部署的,那么每台服务器实例上部署的应用实例都各自拥有一个ServletContext实例。
二、源码分析
1 ServletContext(上)
下面我们先逐个分析ServletContext中servlet3.0之前的规范定义的方法(其中有三个方法是servlet3.0规范定义的,放在一起讲是出于方便的考虑,讲到的时候会特别说明)。
public interface ServletContext {
public String getContextPath();
public ServletContext getContext(String uripath);
public int getMajorVersion();
public int getMinorVersion();
public int getEffectiveMajorVersion();
public int getEffectiveMinorVersion();
public String getServerInfo();
public String getServletContextName();
public String getMimeType(String file);
public void log(String msg);
public void log(String message, Throwable throwable);
public Set<String> getResourcePaths(String path);
public URL getResource(String path) throws MalformedURLException;
public InputStream getResourceAsStream(String path);
public RequestDispatcher getRequestDispatcher(String path);
public RequestDispatcher getNamedDispatcher(String name);
public String getRealPath(String path);
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
public boolean setInitParameter(String name, String value);
public Object getAttribute(String name);
public Enumeration<String> getAttributeNames();
public void setAttribute(String name, Object object);
public void removeAttribute(String name);
// 省略servlet3.0及3.1规范定义的方法
}
1.1 getContextPath
方法返回web应用的上下文路径。就是我们部署的应用的根目录名称。拿Tomcat举例,我们在webapps部署了应用demo。那么方法返 回"/demo"。如果是部署在ROOT下,那么方法返回空字符串""。这里的路径可以再server.xml里面修改,比如我们的demo应用路径修改 为"/test":
<Context docBase="demo" path="/test" reloadable="true" source="org.eclipse.jst.j2ee.server:demo"/>
那么方法按理说会返回"/test"。
但是经过试验,tomcat会初始化2个web应用,路径分别是 "/demo" 和 "/test",且都可以访问成功,若有大神知道原由,还请在评论区指点
1.2 getContext
getContext(String path)(1,参数为 server.xml 中 <context>元素 的 path 属性值
2,不能在 当前servlet 的 init 方法中