Подтвердить что ты не робот

Использование методов PUT и DELETE в Spring MVC

Я пытаюсь использовать RequestMethod.PUT и RequestMethod.DELETE в Spring MVC-контроллере (версия 3.0.2). Существует три метода сопоставления с URL-адресом в классе контроллера Spring следующим образом (PUT, GET и POST соответственно, только для демонстрационной цели).

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

Когда страница загружается, метод GET вызывается как очевидный, но во всех других случаях (при отправке страницы) единственным методом, который вызывается, является POST, метод, обозначенный RequestMethod.PUT никогда не вызывается.


Форма Spring содержит только кнопку отправки и браузер изображений, как

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

Сгенерированный HTML выглядит следующим образом:

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

В моем spring-config.xml (dispatcher-servlet.xml в моем случае), я добавил ссылку на CommonsMultipartResolver:

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

и в моем web.xml файле HiddenHttpMethodFilter настроен следующим образом,

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

Метод PUTDELETE тоже) никогда не вызывается (без исключения или ошибки). Что мне здесь не хватает?


Обновление:

Со следующей конфигурацией в 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>

он выдает следующее исключение.

org.springframework.beans.factory.NoSuchBeanDefinitionException: Нет bean named 'filterMultipartResolver' определен

Если имя dispatcher - это имя сервлета - org.springframework.web.servlet.DispatcherServlet, уже отображенное в web.xml, следующим образом.

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

Я не уверен, что еще нужно? Является ли фильтр HiddenHttpMethodFilter необходимым для реализации на нашем собственном расширении OncePerRequestFilter что-то вроде показанного здесь? (это встроенный класс)

Важные пункты перечислены здесь.

4b9b3361

Ответ 1

Большинство браузеров не поддерживают action=PUT в HTML-формах. Они просто отправят вместо запросов POST. HiddenHttpMethodFilter поможет вам решить эту проблему, но вы должны включить скрытое поле _method=PUT в свою форму. Если вы используете тег spring: form taglib, это будет сделано автоматически для вас, но ваш пример, похоже, использует простой HTML.

NoSuchBeanDefinitionException, скорее всего, является несвязанной проблемой.

Ответ 2

Вы должны изменить свой конфиг.

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

to

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