ServletContext对象详解

ServletContext用来存放全局变量,每个Java虚拟机每个Web项目只有一个ServletContext,这个ServletContext是由Web服务器创建的,来保证它的唯一性。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象通讯。ServletContext对象通常也被称之为Context域对象。

源码

public interface ServletContext {
    // servlet3.0之前的规范定义的方法
    public static final String TEMPDIR = "javax.servlet.context.tempdir";
    public static final String ORDERED_LIBS = "javax.servlet.context.orderedLibs";

    public ServletRegistration.Dynamic addServlet(String servletName, String className);
    public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet);
    public ServletRegistration.Dynamic addServlet(String servletName, Class <? extends Servlet> servletClass);
    public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException;
    public ServletRegistration getServletRegistration(String servletName);
    public Map<String, ? extends ServletRegistration> getServletRegistrations();

    public FilterRegistration.Dynamic addFilter(String filterName, String className);
    public FilterRegistration.Dynamic addFilter(String filterName, Filter filter);
    public FilterRegistration.Dynamic addFilter(String filterName, Class <? extends Filter> filterClass);
    public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException;
    public FilterRegistration getFilterRegistration(String filterName);
    public Map<String, ? extends FilterRegistration> getFilterRegistrations();
    
    public void addListener(String className);
    public <T extends EventListener> void addListener(T t);
    public void addListener(Class <? extends EventListener> listenerClass);
    public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException; 

    public SessionCookieConfig getSessionCookieConfig();
    public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);
    public Set<SessionTrackingMode> getDefaultSessionTrackingModes();
    public Set<SessionTrackingMode> getEffectiveSessionTrackingModes();

    public JspConfigDescriptor getJspConfigDescriptor();

    public ClassLoader getClassLoader();

    public void declareRoles(String... roleNames);

    public String getVirtualServerName();
}

TEMPDIR对应的属性值是个java.io.File对象,表示该ServletContext对应的临时目录。拿tomcat来说,比如有个应用叫demo,那么 demo对应的ServletContext临时目录就是{Tomcat目录}\work\Catalina\localhost\demo。 

ORDERED_LIBS对应的属性值是个java.util.List对象,每个元素表示WEB-INF/lib目录下的 JAR包名称。这些名称的排序是根据它们的web-fragment名称排序的,如果里面没有配 置的话,可能会存在冲突。如果没有在web.xml里面配置或在web-fragment.xml里面配置,那么属性值为null。这里涉及到servlet3.0增加的新特性————web模块化,感兴趣的读者自行去了解,这里不做引申。

方法

1. addServlet()    //提供了编程式的向servlet容器中注入servlet的方式,其达到的效果和在web.xml中配置或者使用WebServlet注解配置servlet是一样的。只不过这种方式更加灵活、动态。addServlet方法返回的是ServletRegistration实例(ervletRegistration.Dynamic集成ServletRegistration),使用这个实例可以进一步配置servlet的注册信息,比如配置url-pattern。

2. createServlet()  //实例化一个servlet,得到一个servlet实例。这个传入的表示servlet类的Class实例必须要有个无参构造函数,因为这个方法的底层实现就是利用发射机制调用默认的无参构造函数进行实例化。这个方法返回的servlet实例没有多大的使用意义,可能还是需要调用相应的addServlet进行注册。

3. getServletRegistration()    //根据servlet名称查找其注册信息,即ServletRegistration实例。

4. getServletRegistrations()    //查询当前servlet上下文中所有的servlet的注册信息。

5. getSessionCookieConfig()    //返回SessionCookieConfig实例,这个实例可以用于获取和设置会话跟踪的cookie的属性。多次调用getSessionCookieConfig方法返回的SessionCookieConfig实例是同一个,说明SessionCookieConfig是单例的。

6. setSessionTrackingModes()    //设置会话的跟踪模式,getDefaultSessionTrackingModes用于获取默认的会话跟踪模式,getEffectiveSessionTrackingModes用于获取有效的会话跟踪模式。默认情况下,getDefaultSessionTrackingModes返回的会话跟踪模式就是有效的。

7. getJspConfigDescriptor()    //获取web.xml和web-fragment.xml中配置的<jsp-config>数据。

8. getClassLoader()    //获取当前servlet上文的类加载器。

9. declareRoles()    //该方法用于申明安全角色。

10. getVirtualServerName()    //返回servlet上下文(即应用)部署的逻辑主机名,比如在本机跑Tomcat,那么这个方法返回"Catalina/localhost"。

ServletContext接口作用域

容器中部署的每一个web应用都有一个ServletContext接口的实例对象与之关联。如果容器被分布在多个虚拟机上,一个web应用将在每一个VM中有一个ServletContext实例。不作为web应用一部分部署的容器中的servlet默认是“默认”web应用的一部分,有一个默认的ServletContext。在分布式容器中。默认ServletContext是非分布式的,并且必须只存在于一个VM中。

例子

//多个Servlet通过ServletContext对象实现数据共享
package gacl.servlet.study;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String data = "xdp_gacl";
        /**
         * ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,
         * 可以通过ServletConfig.getServletContext方法获得ServletContext对象。
         */
        ServletContext context = this.getServletConfig().getServletContext();//获得ServletContext对象
        context.setAttribute("data", data);  //将data存储到ServletContext对象中
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}
package gacl.servlet.study;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo2 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据
        response.getWriter().print("data="+data);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

先运行ServletContextDemo1,将数据data存储到ServletContext对象中,然后运行ServletContextDemo2就可以从ServletContext对象中取出数据了,这样就实现了数据共享,运行结果:

ServletContext对象例子

总结

1. 一个web应用对应一个ServletContext,所以ServletContext的作用范围是整个应用。

2. 一个web应用对应一个ServletContext实例,这个实例是应用部署启动后,servlet容器为应用创建的。ServletContext实例包含了所有servlet共享的资源信息。通过提供一组方法给servlet使用,用来和servlet容器通讯,比如获取文件的MIME类型、分发请求、记录日志等。

版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。