Передача данных в тело запроса 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
, потому что данные содержат версию строки, которая используется для оптимистической блокировки.
Ответы
Ответ 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");
}
});
}
}