(一)问题1
对于Form表单而言,它的提交方式只有两种“GET”和“POST”,这显然无法满足RestFul的“GET/POST/PUT/DELETE”四种风格,怎么办?
(二)解决办法
1.表单中的处理
在表单中埋一个“hidden”,它的“name”属性必须为“_method”,“value”属性为“PUT/DELETE”,这样SpringMVC会自动将该“hidden”控件的“value”解析为请求的方法。
操作类型 | RestFul请求方法 | 表单 | SpringMVC |
---|---|---|---|
查询 | GET | method = GET | RequestMethod.GET |
新增 | POST | method = POST | RequestMethod.POST |
修改 | PUT | method = POST _method = PUT | RequestMethod.PUT |
删除 | DELETE | method = POST _method = DELETE | RequestMethod.DELETE |
2.SpringMVC中的处理
在web.xml中注册过滤器
<!-- 处理表单的RestFul提交方式 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(三)问题2
从上面可知,当我们配置了“HiddenHttpMethodFilter”,同时埋一个<input type="hidden" name="_method" value="PUT"/>
,就可以实现从表单中获取该“hidden”的“value”(HttpServletRequest.getParameter("_method")
),解析出符合RestFul风格的请求方法。
但是这种办法只适用于表单的enctype = application/x-www-form-urlencoded
这种提交方式,而当我们涉及到上传文件时,表单的enctype = multipart/form-data
变成这样,我们的“HiddenHttpMethodFilter”将无法通过httpServletRequest.getParameter("_method")
获取到任何值。因为对于这种表单提交方式,必须通过HttpServletRequest.getInputStream()
进行转换之后,再通过httpServletRequest.getParameter("_method")
才能解析出参数,怎么办?
(四)解决办法
1.配置“MultipartFilter”过滤器
根据上面可知,我们需要在执行“HiddenHttpMethodFilter”过滤器之前就先将参数进行解析,同时我们知道Filter过滤器执行的顺序是我们在“web.xml”中的配置顺序,所以我们需要在“HiddenHttpMethodFilter”过滤器之前配置一个SpringMVC提供的另外一个过滤器“MultipartFilter”。
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<init-param>
<param-name>multipartResolverBeanName</param-name>
<!-- 这是在applicationContext-web.xml中配置的文件上传解析器的id -->
<param-value>multipartResolver</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.配置Spring监听器
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- spring监听器加载的配置文件 -->
<param-value>classpath:spring/root-context.xml</param-value>
</context-param>
<listener>
<!--ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息-->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3.将applicationContext-web.xml中配置的文件上传解析器放到spring监听器的配置文件root-context.xml中