J'essaie d'utiliser RequestMethod.PUT
et RequestMethod.DELETE
dans le contrôleur Spring MVC (version 3.0.2). Il existe trois méthodes mappées avec une URL dans la classe de contrôleur Spring comme suit (PUT, GET et POST respectivement, à des fins de démonstration uniquement).
@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";
}
Lorsque la page est chargée, la méthode GET
est invoquée comme évidente mais dans tous les autres cas (lorsque la page est soumise), la seule méthode à invoquer est POST
, la méthode désignée par RequestMethod.PUT
n'est jamais invoqué.
Le formulaire Spring contient uniquement un bouton d'envoi et un navigateur d'images,
<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>
Le code HTML généré est le suivant,
<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>
Dans mon spring-config.xml
(dispatcher-servlet.xml
dans mon cas), j'ai ajouté une référence à CommonsMultipartResolver
:
<bean id="filterMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
et dans mon web.xml
fichier, HiddenHttpMethodFilter
est configuré comme suit,
<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>
La méthode PUT
(et DELETE
aussi) n'est jamais invoquée (sans exception ni erreur). Qu'est-ce que j'oublie ici?
Mise à jour:
Avec la configuration suivante dans 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>
il lève l'exception suivante.
org.springframework.beans.factory.NoSuchBeanDefinitionException: aucun bean nommé 'filterMultipartResolver' n'est défini
Où le nom dispatcher
est le nom du servlet - org.springframework.web.servlet.DispatcherServlet
déjà mappé dans web.xml comme suit.
<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>
Je ne sais pas quoi d'autre est nécessaire? Le filtre HiddenHttpMethodFilter
est-il requis pour implémenter notre propre extension OncePerRequestFilter
quelque chose comme celui montré ici ? (c'est une classe intégrée)
Les points importants sont répertoriés ici .
La plupart des navigateurs ne prennent pas en charge action=PUT
dans les formulaires HTML. Ils enverront simplement POST
demandes à la place. HiddenHttpMethodFilter vous aidera à contourner le problème, mais vous devez inclure un champ caché _method=PUT
dans votre formulaire. Si vous utilisez la balise spring: form, cela se fera automatiquement pour vous, mais votre exemple semble utiliser du HTML simple.
NoSuchBeanDefinitionException
est très probablement un problème sans rapport.
Vous devez changer votre configuration.
<servlet-name>/*</servlet-name>
à
<servlet-name>[dispatch servlet name]</servlet-name>