2012-11-29 22 views
18

Sto tentando di utilizzare RequestMethod.PUT e RequestMethod.DELETE nel controller MVC Spring (versione 3.0.2). Ci sono tre metodi mappati con un URL nella classe del controller Spring come segue (rispettivamente PUT, GET e POST, solo a scopo dimostrativo).Utilizzo dei metodi PUT e DELETE in Spring MVC

@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"; 
} 

Quando la pagina viene caricata, il metodo GET viene invocato come ovvio, ma in tutti gli altri casi (quando la pagina viene inviata), l'unico metodo da richiamare è POST, il metodo indicato con RequestMethod.PUT è mai invocato.


La forma Primavera contiene solo un pulsante e un browser di immagine come presentare,

<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> 

Il codice HTML generato è il seguente,

<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> 

Nel mio spring-config.xml (dispatcher-servlet.xml nel mio caso), Ho aggiunto un riferimento a CommonsMultipartResolver:

<bean id="filterMultipartResolver" 
     class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> 

e nel mio file web.xml, HiddenHttpMethodFilter è configurato come segue,

<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> 

Il PUT (e DELETE troppo) metodo non viene richiamato (senza alcuna eccezione o errore). Cosa mi manca qui?


Aggiornamento:

con la seguente configurazione in 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> 

viene generata la seguente eccezione.

org.springframework.beans.factory.NoSuchBeanDefinitionException: No fagiolo di nome 'filterMultipartResolver' è definito

Qualora il nome dispatcher è il nome del Servlet - org.springframework.web.servlet.DispatcherServlet già mappato in web.xml come segue.

<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> 

Non sono sicuro di cos'altro è necessario? Il filtro HiddenHttpMethodFilter è necessario per implementare il nostro OncePerRequestFilter estendendoci qualcosa come quello mostrato here? (è una classe built-in)

I punti importanti sono elencati here.

risposta

13

La maggior parte dei browser non supporta action=PUT in moduli HTML. Invieranno semplicemente richieste POST. Lo HiddenHttpMethodFilter ti aiuterà a risolvere il problema, ma devi includere un campo nascosto _method=PUT nel modulo.Se usi la molla: form taglib questo verrà fatto automaticamente per te, ma il tuo esempio sembra usare un semplice HTML.

Il NoSuchBeanDefinitionException è probabilmente un problema non correlato.

+1

sto usando che libreria di tag - ' ...' e il campo nascosto '' è automaticamente incluso in ** l'HTML generato ** come mostrato nel secondo e nel terzo frammento di codice nella domanda. Ho già visto così tanti post su questo sito e altri tutorial. Sto quasi facendo come descritto da loro anche se la cosa non funziona, nel mio caso. Non sono sicuro di cosa mi stia perdendo. Grazie per la risposta. – Tiny

+0

Scusa, ho letto male il tuo post ... mio male. – Guillaume

+0

Il testo, "* NoSuchBeanDefinitionException è probabilmente un problema non correlato *" è corretto. L'unico problema era che non avevo configurato correttamente questo 'org.springframework.web.multipart.commons.CommonsMultipartResolver' e inserito in un file xml sbagliato invece di inserirlo in' applicationContext.xml'. Quindi, stava causando l'eccezione. Ora funziona e viene richiamato il metodo designato con 'RequestMethod.PUT' nel controller Spring. Un problema rimane ancora che 'ServletFileUpload.isMultipartContent (request)' restituisce sempre false. Restituisce vero solo su 'POST'. Conosci la ragione? – Tiny

1

È necessario modificare la configurazione.

<servlet-name>/*</servlet-name> 

a

<servlet-name>[dispatch servlet name]</servlet-name> 
Problemi correlati