首页 > 代码库 > HttpPutFormContentFilter 和 ContextLoaderListener 讲解

HttpPutFormContentFilter 和 ContextLoaderListener 讲解

1 ContextLoaderListener 继承自ContextLoader,并且实现ServletContextListener接口。

肯定得实现这个接口了,不然怎么作为Servlet的监听器呢。。。

ContextLoaderListener 源代码很简单,核心是实现了 ServletContextListener 的contextInitialized和contextDestroyed方法。

因为 contextInitialized和contextDestroyed 方法分别调用了 ContextLoader里面的initWebApplicationContext和closeWebApplicationContext方法

所以核心最终还是 ContextLoader 实现了这个监听器,那这个监听器实现了什么功能呢,我们发现有两个重要属性

contextConfigLocation:即在web.xml里面指定的配置文件所在目录,如果不指定,Spring 会加载WEB_INF目录下,符合 *Context.xml 或 spring*.xml 规则的文件

currentContextPerThread:保存了当前WebApplicationContext

其实监听器的加载过程可以描述为:

先判WebApplicationContext是否已存在,不存在的话则初始化一个XmlWebApplicationContext(WebApplicationContext的子类),并把该实例put到 currentContextPerThread 中。而初始化 XmlWebApplicationContext 时,就跟我们使用 new ClassPathXmlApplicationContext(contextConfigLocation)一样

将我们配置的各种bean都添加到XmlWebApplicationContext中,所以我们知道 ApplicationContext 提供各种 getBean的方法。。。

并且可以发现 ContextLoader还提供了获取当前 WebApplicationContext的静态方法:之所以能获取,是因为initWebApplicationContext初始化方法把创建的XmlWebApplicationContext 塞到了 currentContextPerThread 中

因为 ContextLoaderListener 本质上是创建了一个 WebApplicationContext ,所以你的项目里面,如果不使用 WebApplicationContext 就可以不配置 ContextLoaderListener 节点。

如果不配  ,

<!-- Spring MVC -->  
    <servlet>  
        <servlet-name>teach</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>/WEB-INF/spring-servlet.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>teach</servlet-name>  
        <url-pattern>*.action</url-pattern>  
    </servlet-mapping>  

那么在应用程序如何获取 WebApplicationContext 呢,有多种方式,最简单的就是

WebApplicationContext applicationContext = ContextLoader.getCurrentWebApplicationContext();

 

还有一些更合适的,基于Spring提供的抽象类或者接口,在初始化Bean时注入ApplicationContext

继承自抽象类ApplicationObjectSupport
说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。
Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。

继承自抽象类WebApplicationObjectSupport
说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext

实现接口ApplicationContextAware
说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。
Spring初始化时,会通过该方法将ApplicationContext对象注入。

 

2 HttpPutFormContentFilter 

在讲解这个之前先看看 HiddenHttpMethodFilter

html中form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。可以配置如下:

<filter>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
    <init-param>  
        <param-name>methodParam</param-name>  
        <param-value>_method_</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  

在页面的form表单中设置method为Post,并添加一个如下的隐藏域:

  <input type="hidden" name="_method" value="http://www.mamicode.com/put" />

HttpPutFormContentFilter

由HiddenHttpMethodFilter可知,html中的form的method值只能为post或get,我们可以通过HiddenHttpMethodFilter获取put表单中的参数键值对,而在Spring3中获取put表单的参数键值对还有另一种方法,即使用HttpPutFormContentFilter过滤器。

HttpPutFormContentFilter过滤器的作为就是获取put表单的值,并将之传递到Controller中标注了method为RequestMethod.put的方法中。

与HiddenHttpMethodFilter不同,在form中不用添加参数名为_method的隐藏域,且method不必是post,直接写成put,但该过滤器只能接受enctype值为application/x-www-form-urlencoded的表单,也就是说,在使用该过滤器时,form表单的代码必须如下:

<form action="" method="put" enctype="application/x-www-form-urlencoded">  

......  

</form>  

配置如下:

<filter>  
   <filter-name>httpPutFormcontentFilter</filter-name>  
   <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>  
</filter>  
<filter-mapping>  
   <filter-name>httpPutFormContentFilter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>  

 

HttpPutFormContentFilter 和 ContextLoaderListener 讲解