4.1 ServletContext接口介绍
ServletContext接口定义了servlet运行的web应用程序的一个Servlet视图。容器提供器负责在这个Servlet容器中提供ServletContext接口的实现。使用ServletContext对象,一个Servlet可以记录事件,获取URI指向的资源,并且设置和存储上下文中其他Servlet可以访问的资源。
一个ServletContext位于web服务器的一个已知路径。例如,一个Servlet上下文可以位于http://www.mycorp.com/catalog.。所有的请求以/catalog请求路径开始,就是context path,根据其可以找到Web应用程序关联的ServletContext。
4.2 Scope of a ServletContext Interface(ServletContext的范围)
部署在容器中的Web应用程序都有一个与之关联的ServletContext接口的实例对象。在容器分布于不同的虚拟机的情况下,一个web应用在每个JVM中都有一个ServletContext实例对象。
容器中不作为部署的web应用程序部分的Servlet其实模糊的作为默认web应用程序的部分并且有一个默认的ServletContext。在一个分布式容器中,默认的ServletContext不是分布式并且每个JVM必须只存在一个ServletContext的对象实例。
4.3 Initialization Parameters(初始化参数)
ServletContext接口提供的如下方法允许Servlet访问上下文初始化参数,这些参数与一个web应用程序关联,其由应用程序开发者在部署描述符中指定。
getInitParameter
getInitParameterNames
初始化参数用于传输启动信息。典型的例子是一个Webmaster的邮件例子,或者一个有重要数据的系统的命名。
4.4 Configuration methods(配置方法)
以下方法是Servlet 3.0后添加到ServletContext的方法,有servlets,过滤器和url模式的程序化定义。这些方法只是在应用程序的初始化期间调用,要不调用ServletContextListener的contextInitialized方法或者调用ServletContextInitializer的onStartup方法。为添加Servlet和过滤器,也可以查找与一个Servlet或者过滤器对应的一个Registration对象的实例,或者对所有Servlet或者过滤器对应的所有注册对象的映射。如果ServletContextListener的contextInitialized方法传递的参数ServletContext,既没有在web.xml文件中声明,也没有在fragment.xml文件中声明,也没有使用注解@WebListener,将抛出一个UnsupportedOperationException异常,这对于所有程序化配置的Servlet,过滤器和监听器都适用。
4.4.1 程序化添加和配置Servlets
对于框架开发者程序化的给上下文添加一个Servlet是很有用的。例如,框架能使用这个方法声明一个控制器servlet。这个方法的返回值是一个ServletRegistration或者 ServletRegistration.Dynamic对象,在后面允许你设置servlet其他的参数,像init-params,url-mapping等等。由这个方法的三个重载。
4.4.1.1 addServlet(String servletName, String className)
这个方法允许应用程序程序化声明一个servlet。使用给定的名字和类名给servlet 上下文添加servlet。
4.4.1.2 addServlet(String servletName, Servlet servlet)
这个方法允许应用程序程序化声明一个servlet。使用给定的名字和servlet实例向Servlet上下文添加一个Servlet
4.4.1.3 addServlet(String servletName, Class <? extends Servlet> servletClass)
这个方法允许应用程序 程序化声明一个Servlet。使用给定的Servlet名字和Servlet类的实例向Servlet上下文添加一个Servlet。
4.4.1.4 <T extends Servlet> T createServlet(Class<T> clazz)
这个方法实例化给定的额Servlet类。这个方法必须支持Servlet的所有注解除了@WebServlet。返回的Servlet实例可能在后面定制化,在其通过调用addServlet(String,Servlet)使用ServletContext注册前。
4.4.1.5 ServletRegistration getServletRegistration(String servletName)
这个方法返回给定名字的Servlet的相对应的ServletRegistration,或者如果不存在返回null。如果ServletContext传递给ServletContextListener的contextInitialized方法,并且在web.xml或者web-fragment.xml中没哟声明,也没有使用注解javax.servlet.annotation.WebListener,将抛出一个异常UnsupportedOperationException。
4.4.1.6 Map<String, <? extends ServletRegistration> getServletRegistrations()
这个方法返回ServletRegistration对象的映射,以注册到ServletContext的所有Servlets关联的名字为键。如果没有servlet注册到ServletContext上,将返回一个空的map。返回的map包含与之对应的声明的或者注解的servlet的ServletRegistration对象,也包括通过addServlet方法注册的ServletRegistration对象。这个返回的Map的任何变化必能影响ServletContext。如果ServletContext传递给ServletContextListener的contextInitialized方法,但是其没有在web.xml或者web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,将抛出一个异常UnsupportedOperationException、
4.4.2 Programmatically adding and configuring Filters
4.4.2.1 addFilter(String filterName, String className)
这个方法允许应用程序化的声明一个过滤器。其使用了一个给定名字和类名向web应用程序添加一个过滤器。
4.4.2.2 addFilter(String filterName, Filter filter)
这个方法允许应用程序化的声明一个过滤器。其使用一个给定的名字和过滤器实例向web应用程序添加一个过滤器。
4.4.2.3 addFilter(String filterName, Class <? extends Filter> filterClass)
这个方法允许应用程序化的声明一个过滤器.使用给定的名字和一个servlet类的实例向web应用程序添加一个过滤器、
4.4.2.4 <T extends Filter> T createFilter(Class<T> clazz)
这个方法实例化一个给定的Filter类。这个方法必须支持过滤器的所有可用的注解。这个返回的Filter实例可能在后面定制,通过调用上面提到的addFilter(String, Filter)
注册到ServletContext中。所给的Filter的类必须定义一个默认构造器,用于实例化这个过滤器。
4.4.2.5 FilterRegistration getFilterRegistration(String filterName)
这个方法返回给定的名字的过滤器相对应的FilterRegistration,或者没有与此名字对应的FilterRegistration返回null。如果ServletContext传递给ServletContextListener的contextInitialized方法,但是其没有在web.xml或者web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,将抛出一个异常UnsupportedOperationException.
4.4.2.6 Map<String, <? extends FilterRegistration> getServletRegistrations()
这个方法返回ServletRegistration对象的映射,以注册到这个ServletContext对应的名字为键。如果没有servlet注册到这个ServletContext,将返回一个空的map。Map包含了与所有声明或者注解servlet对应的ServletRegistration对象,也包括通过addFilter方法添加的与所有servlet对应的ServletRegistration对象。对于返回的Map的任何变化不能影响servletContext。如果ServletContext传递给ServletContextListener的contextInitialized方法,但是其没有在web.xml或者web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,将抛出一个异常UnsupportedOperationException.
4.4.3 Programmatically adding and configuring Listeners
4.4.3.1 void addListener(String className)
向ServletContext添加指定类名的监听器。使用与这个ServletContext代表的应用程序关联的类加载器加载给定的类名。,这个类必须实现以下一个或者或者更多的接口。
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
如果ServletContext参数传递给ServletContainerInitializer的onStartup方法,稍后给定名字的类除了实现上述接口外可能也实现了javax.servlet.ServletContextListener。作为这个方法调用的部分,这个容器必须加载指定类名的类来确保它实现了所需接口中的一个。如果给定名字的类实现了一个监听器接口,其调用顺序与申明顺序对应,即,如果其实现了javax.servlet.ServletRequestListener或者javax.servlet.http.HttpSessionListener,那么新的接口要添加到坚挺顺序列表接口的后面。
4.4.3.2 <T extends EventListener> void addListener(T t)
向ServletContext添加给定的监听器。给定的监听器必须是以下接口的实例
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
如果ServletContext参数传递给ServletContainerInitializer的onStartup方法,稍后给定名字的类除了实现上述接口外可能也实现了javax.servlet.ServletContextListener。作为这个方法调用的部分,这个容器必须加载指定类名的类来确保它实现了所需接口中的一个。如果给定名字的类实现了一个监听器接口,其调用顺序与申明顺序对应,即,如果其实现了javax.servlet.ServletRequestListener或者javax.servlet.http.HttpSessionListener,那么新的接口要添加到坚挺顺序列表接口的后面。
4.4.3.3 void addListener(Class <? extends EventListener> listenerClass)
向ServletContext添加指定类类型的监听器。给定的监听器必须是以下接口的监听器实例
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
如果ServletContext参数传递给ServletContainerInitializer的onStartup方法,稍后给定名字的类除了实现上述接口外可能也实现了javax.servlet.ServletContextListener。作为这个方法调用的部分,这个容器必须加载指定类名的类来确保它实现了所需接口中的一个。如果给定名字的类实现了一个监听器接口,其调用顺序与申明顺序对应,即,如果其实现了javax.servlet.ServletRequestListener或者javax.servlet.http.HttpSessionListener,那么新的接口要添加到坚挺顺序列表接口的后面。
4.4.3.4 <T extends EventListener> void createListener(Class<T> clazz)
这个方法实例化了给定EventListener类的实例。给定的事件监听器必须实现以下的接口中的一个或者全部。
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
这个方法实例化一个给定的事件监听器类。这个方法必须支持事件监听器的所有可用的注解。这个返回的EventListener实例可能在后面定制,通过调用上面提到的addListener(T t)
注册到ServletContext中。所给的Filter的类必须定义一个默认构造器,用于实例化这个事件监听器。
4.4.3.5 Annotation processing requirements for programmatically added Servlets, Filters and Listeners (使用注解程序化添加servlets,过滤器和监听器)
当使用程序化的API添加一个servlet或者创建一个过滤器,除了addServlet方法要传递一个实例参数,下面的注解必须在类中自检,除非重写了ServletRegistration.Dynamic /ServletRegistration的API。
@ServletSecurity, @RunAs, @DeclareRoles, @MultipartConfig.
对了监听器和过滤器,注解无需自检。
所有组件(Servlets,过滤器,监听器)的资源诸如的程序化的添加或者创建,除了带参数传递外,当组件是可管理Bean的时候也是支持度额。
4.5 Context Attributes(上下文属性)
一个servlet可以向上下文以一个名字绑定一个对象属性。绑定在一个上下文中的任何属性,其他的servlet是可以访问的,这些servlet是相同web应用程序的一部分。ServletContext接口的以下方法允许访问这个功能:
setAttribute
getAttribute
getAttributeNames
removeAttribute
4.5.1 Context Attributes in a Distributed Container
上下文属性是局部的,其由JVM创建。这样避免ServletContext属性在一个分布式容器中成为一个共享内存存储。当在一个分布式运行环境中信息需要共享的时候,信息应该放在一个session中,存储在一个数据库中,或者设置在一个企业JavaBean的组件中。
4.6 Resource
ServletContext接口提供了直接访问静态内容文档的等级,这些文档时web应用程序的一部分,包括HTML,GIF和JPEG文件,提供了如下方法:
getResource
getResourceAsStream
这两个方法传递一个String参数,其以"/"开头,这个路径是与上下文根路径相对的资源路径或者在一个web应用程序的WEB-INF/lib目录的下一个jar文件的META-INF/resources相对的资源路径。这些方法将首先在web应用程序的上下文的根目录下查找请求资源,如果没有找到,才会查找WEB-INF/lib目录的jar文件。WEB-INF/lib目录下的jar文件的扫描顺序没有定义。这些文件可能存在于这个服务器的文件系统,在一个web应用程序的档案文件,在一个远程服务器或者在其他位置。
这些方法不用于获取动态内容。例如,在JSP规范支持的容器中,getResource("/index.jsp")方法的调用会返回JSP源代码和没有处理的输出。
调用getResourcePaths(String path)方法可以获取能被访问的web应用程序中所有资源列表。
4.7 Multiple Hosts and Servlet Contexts(多主机和Servlet上下文)
web服务器可能支持一个服务器上共享一个IP地址的多个逻辑主机。这种能力有时叫做“虚拟主机”。这种情况下,每个逻辑主机必须有自己的Servlet上下文或者一组Servlet上下文。虚拟主机之间不能共享Servlet上下文的。
4.8 重新加载注意事项
虽然一个容器提供者实现一个类的重新加载计划对于简单的开发是不需要的,但是任何这样的实现必须确保所有的Servlet,和可能使用的类,在单一类的范围内加载。这个要求需要保证按照开发者期望的来表现。作为辅助,回话绑定的监听器的通知全语义应该由使用的容器支持,这在监控回话类重载后终止。
以前容器创建一个新的类加载器来加载一个servlet,这个与类加载器用于加载其他servlets或者用于Servlet上下文的类不同。这会引起Servlet上下文中的对象引用指向不期望的类或者对象,并引起意料不到的行为。这就需要预防新类加载器创建导致的问题。
4.8.1 Temporary Working Directories(临时的工作目录)
每一个Servlet上下文有一个临时的存储目录。每个Servlet容器必须为每个Servlet上下文提供一个私有临时目录并使之通过javax.servlet.context.tempdir的上下文属性可以访问。与这个属性关联的对象必须是java.io.File类型。
The requirement recognizes a common convenience provided in many servlet engine implementations.虽然当Servlet容器重启的时候,容器不需要保持临时目录的内容,但是一个Servlet上下文的临时目录的内容对于运行在servlet容器的的web的其他web应用程序的servlet上下文是不可见的。
本文详细介绍了Servlet上下文的概念,包括其范围、初始化参数、配置方法、上下文属性、资源访问以及在多主机环境下的行为。重点阐述了如何通过程序化的方式添加Servlet、过滤器和监听器,并讨论了资源加载和上下文属性的使用场景。
935

被折叠的 条评论
为什么被折叠?



