我正在使用REST客户端进行测试。我使用完全相同的查询,只需将方法从POST
更改为DELETE
。我在Spring Boot 2.0.1中使用相同的方法 - 只需将注释从@PostMapping
更改为@DeleteMapping
。
@DeleteMapping(value = "/receiver")
public ResponseEntity<Response> doOperation(@RequestParam(value = "name") String name) {
return new ResponseEntity<>(HttpStatus.OK);
}
一旦我更改为DELETE
,我就会收到错误:
"Required String parameter 'name' is not present"
我已经用@PutMapping测试了它 - 也可以。
我做错了什么?
更新1
删除请求:
DELETE /api/v1/wud/receiver?action=something HTTP/1.1
Cookie: PHPSESSID=e6b750be296f28174196817f126b367a
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: somehost:9443
Connection: close
User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 10
name=ASDEF
响应提到错误
POST请求:
POST /api/v1/wud/receiver?action=something HTTP/1.1
Cookie: PHPSESSID=e6b750be296f28174196817f126b367a
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: somehost:9443
Connection: close
User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 10
name=ASDEF
回复是200
更新2
我能够使用原始的spring示例gs-rest-service在非常简单的设置中重现它。我已经在github HERE上分享了它.MockMvc测试通过时很有意思,但它在现实中并没有起作用。
我将用Spring启动填充错误
答案 0 :(得分:2)
这不是Spring
的问题,但嵌入式tomcat
本身作为DELETE
请求的主体通常会被忽略。
这是一种解决方法。
对于spring-boot
2.0 +,
@Configuration
public class TomcatConfig implements TomcatConnectorCustomizer
{
@Override
public void customize(Connector connector) {
connector.setParseBodyMethods("POST,PUT,DELETE");
}
}
可以在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");
}
};
}
但这是一种不好的做法。因为您最终执行了POST
,但将其称为DELETE
api。
答案 1 :(得分:2)
不应该使用DELETE请求发送有效负载。 DELETE请求就像rm命令,您要求服务器删除资源。
发送有效负载未定义,可能因服务器而异
来自RFC:
A payload within a DELETE request message has no defined semantics;
sending a payload body on a DELETE request might cause some existing
implementations to reject the request.
答案 2 :(得分:1)
从您的问题来看,您似乎正在@RequestBody
使用@PostMapping
,而是使用@DeleteMapping
@RequestParam
。{/ p>
此外,您正在使用请求正文而不是url参数调用DELETE api。根据您的请求信息,我看到:
DELETE /api/v1/wud/receiver?action=something HTTP/1.1
但你必须像这样调用你的删除API:
DELETE /api/v1/wud/receiver?action=something&name=something
Here ---------^^^^^
使用curl,您可以使用:
curl -X DELETE '{{url}}/api/v1/wud/receiver?action=something&name=something'
另一方面,如果name
param不是必需的,那么您可以使用:
@RequestParam(value = "name", required = false) String name