购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 Servlet上下文

本节将详细介绍Servlet上下文ServletContext接口的作用及配置方式。

2.3.1 ServletContext接口介绍

ServletContext接口定义了Servlet运行在Web应用的视图。容器供应商负责提供Servlet容器的ServletContext接口实现。Servlet可以使用ServletContext对象记录事件,获取URL引用的资源,存取当前上下文中其他Servlet可以访问的属性。

ServletContext是Web服务器中已知路径的根。例如,Servlet上下文可以从“http://www.waylau.com/catalog”找到,“/catalog”请求路径称为上下文路径,所有以其开头的请求都会被路由到与ServletContext相关联的Web应用中。

2.3.2 ServletContext接口作用域

每一个部署到容器的Web应用都有一个ServletContext接口的实例与之关联。当容器分布在多台虚拟机时,每个JVM的Web应用将会有一个ServletContext实例。

如果容器内的Servlet没有部署到Web应用中,则作为“默认”Web应用的一部分,并有一个默认的ServletContext。在分布式的容器中,默认的ServletContext是非分布式的,且仅存在于一个JVM中。

2.3.3 初始化参数

以下ServletContext接口方法允许Servlet访问由应用开发人员在Web应用的部署描述符中指定的上下文初始化参数。

·getInitParameter

·getInitParameterNames

应用开发人员使用初始化参数来表达配置信息。代表性的例子是一个网络管理员的E-mail地址,或保存关键数据的系统名称。

2.3.4 配置方法

下面的方法从Servlet 3.0开始添加到ServletContext,可以启用编程方式定义Servlet、Filter和其映射到的URL模式。这些方法只能从ServletContextListener实现的contexInitialized方法,或者ServletContainerInitializer实现的onStartup方法进行应用初始化的过程中调用。除了添加Servlet和Filter,也可以查找关联到Servlet或Filter的一个Registration对象实例,或者关联到Servlet或Filter的所有Registration对象的Map。

如果ServletContext传到了ServletContextListener的contextInitialized方法,但该ServletContext-Listener既没有在web.xml或web-fragment.xml中声明,也没有使用@WebListener注解,则在ServletContext中定义的用于Servlet、Filter和Listener编程式配置的所有方法必须抛出Unsupported-OperationException。

1.编程式添加和配置Servlet

编程式添加Servlet到上下文对框架开发者是很有用的。例如,框架可以使用这个方法声明一个控制器Servlet,该方法将返回一个ServletRegistration或ServletRegistration.Dynamic对象,并允许进一步配置如init-params、url-mapping等Servlet的其他参数。下面描述了该方法的6个重载版本。

(1)addServlet(String servletName, String className):该方法允许应用以编程方式声明一个Servlet。它添加给定的Servlet名称和class名称到Servlet上下文。

(2)addServlet(String servletName, Servlet servlet):该方法允许应用以编程方式声明一个Servlet。它添加给定的名称和Servlet实例的Servlet到Servlet上下文。

(3)addServlet(String servletName, Class<?extends Servlet>servletClass):该方法允许应用以编程方式声明一个Servlet。它添加给定的名称和Servlet类的一个实例的Servlet到Servlet上下文。

(4)T createServlet(Class clazz):该方法实例化一个给定的Servlet类。该方法必须支持适用于Servlet的除@WebServlet外的所有注解。返回的Servlet实例通过调用上面定义的addServlet(String, Servlet)注册到ServletContext之前,可以进行进一步的定制。

(5)ServletRegistration getServletRegistration(String servletName):该方法返回与给定名称的Servlet相关的ServletRegistration,如果没有与其相关的ServletRegistration则返回null。如果ServletContext传到了ServletContextListener的contextInitialized方法,但该ServletContextListener既没有在web.xml或web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,则必须抛出UnsupportedOperationException。

(6)Map getServletRegistrations():该方法返回ServletRegistration对象的Map,由名称作为键并对应注册到ServletContext的所有Servlet。如果没有Servlet注册到ServletContext则返回一个空的Map。返回的Map包括所有声明和注解的Servlet对应的ServletRegistration对象,也包括那些使用addServlet方法添加的所有Servlet对应的ServletRegistration对象。返回的Map的任何改变都不影响ServletContext。如果ServletContext传到了ServletContextListener的contextInitialized方法,但该ServletContextListener既没有在web.xml或web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,则必须抛出UnsupportedOperationException。

2.编程式添加和配置Filter

(1)addFilter(String filterName, String className):该方法允许应用以编程方式声明一个Filter。它添加给定的名称和类名称的Filter到Web应用。

(2)addFilter(String filterName, Filter filter):该方法允许应用以编程方式声明一个Filter。它添加给定的名称和Filter实例的Filter到Web应用。

(3)addFilter(String filterName, Class<?extends Filter>filterClass):该方法允许应用以编程方式声明一个Filter。它添加给定的名称和Filter类的一个实例的Filter到Web应用。

(4)T createFilter(Class clazz):该方法实例化一个给定的Filter。该方法必须支持适用于Filter的所有注解。返回的Filter实例通过调用上面定义的addServlet(String, Filter)注册到ServletContext之前,可以进行进一步的定制。给定的Filter类必须定义一个用于实例化的空参构造器。

(5)FilterRegistration getFilterRegistration(String filterName):该方法返回与给定名称的Filter相关的FilterRegistration,如果没有与其相关的FilterRegistration则返回null。如果ServletContext传到了ServletContextListener的contextInitialized方法,但该ServletContextListener既没有在web.xml或web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,则必须抛出UnsupportedOperationException。

(6)Map getFilterRegistrations():该方法返回FilterRegistration对象的Map,由名称作为键并对应注册到ServletContext的所有Filter。如果没有Filter注册到ServletContext,则返回一个空的Map。返回的Map中包括所有声明和注解的Filter对应的FilterRegistration对象,也包括那些使用addFilter方法添加的所有Servlet对应的ServletRegistration对象。返回的Map的任何改变都不影响ServletContext。如果ServletContext传到了ServletContextListener的contextInitialized方法,但该ServletContextListener既没有在web.xml或web-fragment.xml中声明,也没有使用javax.servlet.annotation.WebListener注解,则必须抛出UnsupportedOperationException。

3.编程式添加和配置Listener

(1)void addListener(String className):往ServletContext添加给定类名的监听器。ServletContext将使用由与应用关联的classloader加载的该给定名称的class,且它们必须实现一个或多个以下接口。

·javax.servlet.ServletContextAttributeListener

·javax.servlet.ServletRequestListener

·javax.servlet.ServletRequestAttributeListener

·javax.servlet.http.HttpSessionListener

·javax.servlet.http.HttpSessionAttributeListener

·javax.servlet.http.HttpSessionIdListener

(2)void addListener(T t):往ServletContext添加一个给定的监听器。给定的监听器实例必须实现一个或多个以下接口。

·javax.servlet.ServletContextAttributeListener

·javax.servlet.ServletRequestListener

·javax.servlet.ServletRequestAttributeListener

·javax.servlet.http.HttpSessionListener

·javax.servlet.http.HttpSessionAttributeListener

·javax.servlet.http.HttpSessionIdListener

(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

·javax.servlet.http.HttpSessionIdListener

(4)void createListener(Class clazz):该方法实例化给定的EventListener类。给定的Event-Listener类必须实现至少一个以下接口。

·javax.servlet.ServletContextAttributeListener

·javax.servlet.ServletRequestListener

·javax.servlet.ServletRequestAttributeListener

·javax.servlet.http.HttpSessionListener

·javax.servlet.http.HttpSessionAttributeListener

·javax.servlet.http.HttpSessionIdListener

4.用于编程式添加Servlet、Filter和Listener的注解处理需求

除了需要一个实例的addServlet外,当使用编程式API添加Servlet或创建Servlet时,以下类中的有关注解必须被内省,且其定义的元数据必须被使用,除非它被ServletRegistration.Dynamic或ServletRegistration中调用的API覆盖了。

2.3.5 上下文属性

Servlet可以通过名称将对象属性绑定到上下文。同一个Web应用内的任何Servlet都可以使用绑定到上下文的属性,以下ServletContext接口中的方法允许访问此功能。

·setAttribute

·getAttribute

·getAttributeNames

·removeAttribute

在JVM中创建的上下文属性是本地的,这可以防止从一个分布式容器的共享内存存储中获取ServletContext属性。当需要在运行在分布式环境的Servlet之间共享信息时,该信息应该被放到会话中或存储到数据库,或者设置到Enterprise JavaBeans(企业级JavaBean)组件中。

2.3.6 资源

ServletContext接口提供了直接访问Web应用中仅是静态内容层次结构的文件的方法,包括HTML、GIF和JPEG文件等。

·getResource

·getResourceAsStream

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源码而不是处理后的输出。 U/uqr8bPRAErbkF2D5/NOHWafyX7mqyCQ9Ya0wgN6ul7nIet9UXDUtfqJsgwU8PR

点击中间区域
呼出菜单
上一章
目录
下一章
×