Передача данных в тело запроса DELETE - программирование
Подтвердить что ты не робот

Передача данных в тело запроса DELETE

У меня есть два метода контроллера MVC Spring. Оба получат те же данные в теле запроса (в формате HTLM POST: version=3&name=product1&id=2), но один метод обрабатывает запросы PUT и другой DELETE:

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.PUT)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.DELETE)
@ResponseBody
public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {

//...
}

В первом методе все поля аргумента product корректно инициализируются. Во втором случае инициализируется только поле id. Другие поля null или 0. (id, вероятно, инициализируется из-за переменной пути id).

Я вижу, что объект HttpServletRequest содержит значения для всех полей тела запроса (version=3&name=product1&id=2). Они просто не отображаются в поля параметра product.

Как я могу заставить второй метод работать?

Я также попытался использовать аннотированные параметры @RequestParam. В методе, обрабатывающем запросы PUT, он работает. В методе DELETE я получаю исключение: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'version' is not present.

Мне нужно передать данные в теле запросов DELETE, потому что данные содержат версию строки, которая используется для оптимистической блокировки.

4b9b3361

Ответ 1

Проблема не в проблеме Spring, а в проблеме Tomcat.

По умолчанию Tomcat будет анализировать только аргументы, которые находятся в стиле формы, когда метод HTTP POST (по крайней мере для версии 7.0.54, который я проверил, но он, вероятно, одинаковый для всех версий Tomcat 7).

Чтобы иметь возможность обрабатывать методы DELETE, вам также нужно установить атрибут parseBodyMethods для Tomcat Connector. Конфигурация разъема выполняется в server.xml.

Ваш обновленный соединитель, скорее всего, будет выглядеть следующим образом:

<Connector port="8080" protocol="HTTP/1.1" 
           connectionTimeout="20000"
           redirectPort="8443"
           parseBodyMethods="POST,PUT,DELETE"
           URIEncoding="UTF-8" />

Здесь - страница документации для настройки соединителей Tomcat.

Как только вы настроите Tomcat для анализа параметров, Spring будет работать нормально (хотя в вашем случае вам, вероятно, потребуется удалить @RequestBody из метода контроллера)

Ответ 2

Вы можете попробовать добавить аннотацию @RequestBody к аргументу Product.

Но если вам просто нужно передать информацию о версии, использование параметра запроса более подходит.

Итак, добавьте новый аргумент в свой метод delete @RequestParam ( "version" ) int, а при вызове метода delete передайте параметр запроса, например ..ajax/products/123?version=1

Как вы сказали, параметр запроса не работает для вас при удалении, можете ли вы указать точный URL-адрес, который вы использовали, и подпись метода?

Ответ 3

Spring boot 1.5. *

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory(){
        @Override
        protected void customizeConnector(Connector connector) {
            super.customizeConnector(connector);
            connector.setParseBodyMethods("POST,PUT,DELETE");
        }
    };
}

Ответ 4

Передача данных в теле запроса DELETE

@Component открытый класс CustomiseTomcat реализует WebServerFactoryCustomizer {

@Override
public void customize(TomcatServletWebServerFactory factory) {

    factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
        @Override
        public void customize(Connector connector) {
            connector.setParseBodyMethods("POST,PUT,DELETE");
        }
    });
}

}