Servlet Context
1. ServletContext接口介绍
ServletContext接口定义了运行着该servlet的Web应用程序的servlet视图。容器提供者负责提供servlet容器中的ServletContext接口的实现。使用ServletContext对象,servlet可以记录事件,获取对资源的URL引用,并设置和存储上下文中的其他servlet可以访问的属性。ServletContext植根于Web服务器中的已知路径。例如,一个servlet上下文可能位于http://example.com/catalog。 所有以/catalog请求路径开头的请求(称为上下文路径)都被路由到与ServletContext关联的Web应用程序。
2.ServletContext接口的作用域
与部署到容器中的每个Web应用程序相关联的ServletContext接口有一个实例对象。在容器分布于许多虚拟机的情况下,Web应用程序将为每个JVM提供ServletContext的实例。
容器中的未作为Web应用程序的一部分部署的servlet是“缺省”Web应用程序的隐式部分,并且具有默认的ServletContext。在分布式容器中,默认的ServletContext是不可分配的,并且必须只存在于一个JVM中。
3.初始化参数
ServletContext接口的以下方法允许servlet访问与应用程序开发人员在部署描述符中指定的Web应用程序相关的上下文初始化参数:
getInitParameter
getInitParameterNames
应用程序开发人员使用初始化参数来传递设置信息。典型的例子是一个站长的电子邮件地址,或者一个拥有重要数据的系统的名字。
4. 配置方法
自Servlet 3.0启用了Servlet、过滤器和它们映射到的url模式的编程定义,所以以下方法被添加到ServletContext中。这些方法只能在应用程序从 ServletContextListener实现的contexInitialized方法或从 ServletContainerInitializer实现的onStartup方法的初始化期间被调用。除了添加Servlet和过滤器之外,还可以查找与Servlet或过滤器对应的注册对象的实例,或为Servlet或过滤器的所有注册对象的映射。如果ServletContext传递到ServletContextListener的contextInitialized方法中,但是ServletContextListener在web.xml或web-fragment.xml中没有被声明,也没有被注解@WebListener,那么在ServletContext中所定义的对于servlet、筛选器和监听器的编程配置的所有方法,都必须抛出UnsupportedOperationException。
4.1 编码添加和配置servlet
The ability to programmatically add a servlet to a context is useful for framework developers. For example a framework could declare a controller servlet using this method. The return value of this method is a ServletRegistration or a ServletRegistration.Dynamic object which further allows you to setup the other parameters of the servlet like init-params, url-mappings etc. There are three overloaded versions of the method as described below.
以编程方式向上下文添加servlet的能力对框架开发人员非常有用。例如,一个框架可以使用这个方法声明一个控制器servlet。此方法的返回值为ServletRegistration或ServletRegistration。动态对象进一步允许您设置servlet的其他参数,如init-params、url映射等。
- addServlet(String servletName, String className)
该方法允许应用程序以编程方式声明servlet。它使用给定的名称添加servlet,并将类名添加到servlet上下文。
addServlet(String servletName, Servlet servlet)
该方法允许应用程序以编程方式声明servlet。它使用给定的名称添加servlet,并将servlet实例添加到servlet上下文。addServlet(String servletName, Class <? extends Servlet>
servletClass)
该方法允许应用程序以编程方式声明servlet。它使用给定的名称添加servlet,并将servlet类的实例添加到servlet上下文。addJspFile(String servletName, String jspfile)
该方法允许应用程序以编程方式声明jsp。它将jsp添加到给定的名称,并将servlet类的实例与servlet上下文对应起来。<T extends Servlet> T createServlet(Class<T> clazz)
该方法实例化给定的Servlet类。该方法必须支持所有适用于servlet的注解,除了@WebServlet。返回的Servlet实例可以通过调用addServlet(String, Servlet),在ServletContext注册之前进一步定制。ServletRegistration getServletRegistration(String servletName)
该方法返回对应于给定名称的servlet的ServletRegistration,如果该名称下不存在ServletRegistration,则返回null。如果ServletContext传递到未在web.xml和web-fragment.xml中定义且j没有注解avax.servlet.annotation.WebListener注释的ServletContextListener的contextInitialized方法,将抛出UnsupportedOperationException。
- Map<String, ? extends ServletRegistration> getServletRegistrations()
该方法返回一个ServletRegistration对象的映射,该映射由与ServletContext注册的所有servlet对应的名称键入。如果没有在ServletContext注册的servlet,则返回空映射。返回的映射包括与所有声明的和带注释的servlet对应的ServletRegistration对象,以及与通过一个addServlet和addJspFile方法添加的所有servlet对应的ServletRegistration对象。返回的映射的任何更改都不应影响ServletContext。如果ServletContext传递到未在web.xml和web-fragment.xml中定义且j没有注解avax.servlet.annotation.WebListener注释的ServletContextListener的contextInitialized方法,将抛出UnsupportedOperationException。
4.2 编码添加和配置filter
4.3 编码添加和配置监听器
4.4 编码配置session超时时间
4.5 编码配置字符集编码
5.Context属性
servlet可以通过名称将对象属性绑定到上下文。绑定到上下文的任何属性都可用于同一Web应用程序的任何其他servlet。下面的ServletContext接口方法允许访问这个功能:
- setAttribute
- getAttribute
- getAttributeNames
- removeAttribute
5.1 Context Attributes in a Distributed Container
上下文属性是创建它们的JVM的本地属性。这将防止ServletContext属性成为分布式容器中的共享内存存储。当servlet之间需要共享的信息运行在分布式环境中,信息应该放在一个会话(见第七章“会话”),存储在数据库中,或设置在一个Enterprise javabean™组件。
6. Resources
ServletContext接口只提供了静态内容文档的层次结构,这些文档是Web应用程序的一部分,包括HTML、GIF和JPEG文件,通过ServletContext接口的下列方法:
- getResource
- getResourceAsStream
getResource和getresour流方法以一个字符串作为参数,它提供了相对于上下文的根的资源的路径,或者相对于web应用程序的 WEB-INF/lib目录中的JAR文件的META-INF/resources目录。如果在WEB-INF/lib中的一个JAR文件的META-INF/resources条目中有一个WEB-INF条目,那么它和所有子条目只能作为静态资源可用。从这样的WEB-INF条目中不会将类或jar放在上下文类路径上,也不会处理Servlet特定的描述符。在查看web-inf/lib目录中的任何JAR文件之前,这些方法将首先搜索web应用程序上下文的根。在WEB-INF/lib目录中JAR文件的顺序是未定义的。这种层次的文档可能存在于服务器的文件系统中,在Web应用程序存档文件中,在远程服务器上,或者在其他位置。
这些方法不用于获取动态内容。例如,在一个支持JavaServer Pages™specification1的容器中,一个以getResource("/index.jsp")的形式方法调用将返回JSP源代码,而不是处理输出。有关访问动态内容的更多信息,请参见第9章“调度请求”。
可以使用getResourcePaths(String path)方法访问Web应用程序中资源的完整列表。在本规范的API文档中可以找到该方法的语义的完整细节。
7. 多个主机和Servlet上下文
Web服务器可以支持在服务器上共享一个IP地址的多个逻辑主机。这种能力有时被称为“虚拟主机”。在这种情况下,每个逻辑主机必须有自己的servlet上下文或servlet上下文集。不能在虚拟主机之间共享Servlet上下文。
ServletContext接口的getVirtualServerName方法允许访问部署ServletContext的逻辑主机的配置名称。Servlet容器可能支持多个逻辑主机。此方法必须为部署在逻辑主机上的所有servlet上下文返回相同的名称,并且该方法返回的名称必须是不同的、稳定的每个逻辑主机,并且适合于将服务器配置信息与逻辑主机关联起来。
8.重新加载注意事项
虽然不需要一个容器提供程序来实现类重载方案,但是任何这样的实现都必须确保所有的servlet和它们可能使用的类都被加载到一个类装入器的范围内。需要这样的需求来保证应用程序的行为符合开发人员的期望。作为一个开发辅助工具,通知到会话绑定侦听器的完整语义应该由容器来支持,以便在类重载时的会话终止监视中使用。
前几代容器创建了新的类装入器来加载servlet,这与用于装载servlet上下文中的其他servlet或类的类加载器截然不同。这可能导致servlet上下文中的对象引用指向意外的类或对象,并导致意外的行为。该需求是为了防止新类装入器的需求生成所引起的问题。
8.1 临时工作目录
每个servlet上下文都需要一个临时存储目录。Servlet容器必须为每个Servlet上下文提供一个私有临时目录,并通过javax.servlet.context.tempdir上下文属性提供它。与该属性关联的对象必须是java.io.File类型的。
该需求识别了许多servlet引擎实现中提供的公共便利。当servlet容器重新启动时,容器并不需要维护临时目录的内容,但是需要确保一个servlet上下文的临时目录的内容对运行在servlet容器上的其他Web应用程序的servlet上下文不可见。