ejemplo - Usando los métodos PUT y DELETE en Spring MVC
post jquery ejemplos (2)
Debes cambiar tu config.
<servlet-name>/*</servlet-name>
a
<servlet-name>[dispatch servlet name]</servlet-name>
Estoy tratando de usar RequestMethod.PUT
y RequestMethod.DELETE
en el controlador Spring MVC (versión 3.0.2). Hay tres métodos asignados con una URL en la clase de controlador Spring de la siguiente manera (PUT, GET y POST respectivamente, solo para fines de demostración).
@RequestMapping(method = {RequestMethod.PUT}, value = {"admin_side/Temp"}, headers = {"content-type=multipart/form-data"})
public String update(@ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) {
if (ServletFileUpload.isMultipartContent(request)) {
System.out.println("true");
}
System.out.println("Request method PUT");
return "admin_side/Temp";
}
@RequestMapping(method = {RequestMethod.GET}, value = {"admin_side/Temp"})
public String showForm(@ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) {
System.out.println("Request method GET");
return "admin_side/Temp";
}
@RequestMapping(method = {RequestMethod.POST}, value = {"admin_side/Temp"})
public String onSubmit(@ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) {
System.out.println("Request method POST");
return "admin_side/Temp";
}
Cuando se carga la página, el método GET
se invoca como obvio, pero en todos los demás casos (cuando se envía la página), el único método que se invoca es POST
, el método designado con RequestMethod.PUT
nunca se invoca.
El formulario Spring contiene solo un botón de envío y un navegador de imágenes como
<form:form id="mainForm"
name="mainForm"
method="PUT"
action="Temp.htm"
enctype="multipart/form-data"
commandName="tempBean">
<input type="file" id="myFile" name="myFile"/>
<input type="submit" id="btnSubmit" name="btnSubmit" value="Submit"/>
</form:form>
El HTML generado es el siguiente,
<form id="mainForm"
name="mainForm"
action="Temp.htm"
method="post"
enctype="multipart/form-data">
<input type="hidden" name="_method" value="PUT"/>
<!--This hidden field is implicitly included-->
<input type="file" id="myFile" name="myFile"/>
<input type="submit" id="btnSubmit" name="btnSubmit" value="Submit"/>
</form>
En mi spring-config.xml
( dispatcher-servlet.xml
en mi caso), he agregado una referencia a CommonsMultipartResolver
:
<bean id="filterMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
y en mi archivo web.xml
, HiddenHttpMethodFilter
está configurado de la siguiente manera,
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<init-param>
<param-name>multipartResolverBeanName</param-name>
<param-value>filterMultipartResolver</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
El método PUT
(y DELETE
también) nunca se invoca (sin excepción o error). ¿Que me estoy perdiendo aqui?
Actualización:
Con la siguiente configuración en web.xml
,
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<init-param> <!-- Makes no difference, if excluded. -->
<param-name>multipartResolverBeanName</param-name>
<param-value>filterMultipartResolver</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<servlet-name>dispatcher</servlet-name> <!--Changed from /* to dispatcher-->
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<servlet-name>dispatcher</servlet-name> <!--Changed from /* to dispatcher-->
</filter-mapping>
arroja la siguiente excepción.
org.springframework.beans.factory.NoSuchBeanDefinitionException: no se ha definido ningún bean denominado ''filterMultipartResolver''
Donde el nombre dispatcher
es el nombre del Servlet - org.springframework.web.servlet.DispatcherServlet
ya asignado en web.xml de la siguiente manera.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
No estoy seguro de qué más se necesita? ¿ HiddenHttpMethodFilter
requiere el filtro HiddenHttpMethodFilter
para implementar en nuestra propia extensión OncePerRequestFilter
algo como el que se muestra here ? (Es una clase incorporada)
Los puntos importantes se enumeran here .
La mayoría de los navegadores no admiten action=PUT
en formularios HTML. Simplemente enviarán solicitudes POST
lugar. El HiddenHttpMethodFilter lo ayudará a solucionar el problema, pero debe incluir un campo oculto _method=PUT
en su formulario. Si usa el archivo spring: form taglib, esto se hará automáticamente por usted, pero su ejemplo parece usar HTML plano.
La NoSuchBeanDefinitionException
es probablemente un problema no relacionado.