2012-11-29 11 views
18

Próbuję użyć RequestMethod.PUT i RequestMethod.DELETE w kontroler Spring MVC (wersja 3.0.2). Istnieją trzy metody mapowane za pomocą adresu URL w klasie kontrolera Spring w następujący sposób (odpowiednio PUT, GET i POST, tylko dla celów demonstracyjnych).Korzystanie z metod PUT i DELETE na wiosnę 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"; 
} 

Gdy strona jest załadowany, metoda GET wywoływana jest tak oczywiste, ale we wszystkich innych przypadkach (gdy strona jest składany), jedynym sposobem, aby być wywołana jest POST metoda oznaczone RequestMethod.PUT nigdy nie jest przywoływany.


Postać Wiosna zawiera tylko przycisk i przeglądarkę obrazu jako przedstawienia,

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

Wygenerowany HTML jest następująca,

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

W moim spring-config.xml (dispatcher-servlet.xml w moim przypadku), Dodałem odniesienie do CommonsMultipartResolver:

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

w moim pliku web.xml, HiddenHttpMethodFilter jest skonfigurowany w następujący sposób

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

PUT (i DELETE zbyt) metoda nie jest wywoływany (bez wyjątku lub błędu). Czego tu mi brakuje?


Update:

o następującej konfiguracji w 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> 

generuje następującym wyjątkiem.

org.springframework.beans.factory.NoSuchBeanDefinitionException: Nie fasola nazwie 'filterMultipartResolver' definiuje

Jeżeli nazwa dispatcher to nazwa Servlet - org.springframework.web.servlet.DispatcherServlet już odwzorowane w web.xml następująco.

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

Nie jestem pewien, co jeszcze jest potrzebne? Czy filtr HiddenHttpMethodFilter jest wymagany do wdrożenia na naszym własnym rozszerzonym OncePerRequestFilter czymś podobnym do pokazanego here? (jest to klasa wbudowana)

Ważne punkty są wymienione here.

Odpowiedz

13

Większość przeglądarek nie obsługuje action=PUT w formularzach HTML. Zamiast tego wyślą po prostu żądania POST. The HiddenHttpMethodFilter pomoże ci ominąć problem, ale w twoim formularzu musisz umieścić ukryte pole _method=PUT.Jeśli użyjesz taglib sprężyny: form, zrobi to automatycznie dla ciebie, ale twój przykład wydaje się używać zwykłego HTML.

Najprawdopodobniej jest to niezwiązany problem z numerem NoSuchBeanDefinitionException.

+1

Używam tego znacznika biblioteka - '' ... i ukryte pole '" jest automatycznie dołączane do ** wygenerowanego HTML **, jak pokazano w drugim i trzecim fragmencie kodu w pytaniu. Widziałem już wiele postów na tej stronie, a także inne samouczki. Już prawie robię to, jak je opisałem, chociaż to nie działa, w moim przypadku. Nie jestem pewien, czego mi brakuje. Dziękuję za odpowiedź. – Tiny

+0

Przepraszamy, źle odczytałem twój wpis ... mój zły. – Guillaume

+0

Twój tekst, "* Wyjątek NoSuchBeanDefinitionException jest najprawdopodobniej niepowiązanym *" "jest poprawny. Jedyny problem polegał na tym, że źle zinterpretowałem ten "org.springframework.web.multipart.commons.CommonsMultipartResolver" i umieściłem go w niewłaściwym pliku xml zamiast umieszczać go w 'applicationContext.xml'. Stąd powodował wyjątek. Teraz działa i wywoływana jest metoda oznaczona 'RequestMethod.PUT' w kontrolerze Spring. Jedynym problemem pozostaje to, że 'ServletFileUpload.isMultipartContent (request)' zawsze zwraca wartość false. Zwraca true tylko na 'POST'. Czy znasz przyczynę? – Tiny

1

Powinieneś zmienić konfigurację.

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

do

<servlet-name>[dispatch servlet name]</servlet-name> 
Powiązane problemy