我有一个简单的servlet如下:
@RestController
public class TestServlet {
@RequestMapping(value = "/test1")
public String test1() {
return "test1";
}
@RequestMapping(value = "/test2")
public String test2(@RequestBody TestClass req) {
return "test2";
}
public static class TestClass {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
但只有没有接收参数的servlet才能正常工作:
作品:http://localhost:8080/test1
不起作用:http://localhost:8080/test2?value=1234
org.springframework.http.converter.HttpMessageNotReadableException: 缺少必需的请求正文:public java.lang.String
为什么@RequestBody
注释不起作用?我错过了一件重要的作品吗?
答案 0 :(得分:4)
@Controller和@RestController之间的一个区别是你不必编写@RequestBody和@ResponseBody,这意味着你的控制器方法中没有注释的任何参数(比如@PathVariable, @ModelAttribute ....)将隐式具有@RequestBody,因此必须作为HTTP实体主体进行POST。所以你需要发送JSON / XML作为POST的一部分。你所做的是作为URL的一部分发送数据,这使得它成为请求参数而不是正文数据,你需要@RequestParam来从URL中提取数据。
另外,我建议你使用@ GetMapping / @ PostMapping或在@RequestMapping注释中包含method参数,你不太可能想要一个服务用于POST和GET,所以你应该是在控制器方法描述中尽可能具体,以限制错误情况。
答案 1 :(得分:2)
第二个URL不起作用的原因是因为在使用@RequestBody时,您发送到端点的数据需要通过请求标头中的data
属性来完成。将?attr=value
附加到正在params
标题中发送属性的网址时。
有两种方法可以解决这个问题:
将您的端点更改为以下内容:
public String test2(@RequestParam("value") TestClass req) {
//Endpoint code
}
将您的端点更改为以下内容:
@RequestMapping(value="test2",method=RequestMethod.POST)
public String test2(@RequestBody TestClass req){
//Endpoint code
}
并使您的通话类似于此(例如angularjs):
http.post({url:/*url*/,data:/*object to send*/});
第二个选项很可能就是你想要的东西,因为它看起来你正在尝试将json对象发送到你的端点,我相信你只能通过发出POST请求而不是GET请求来做到这一点< / p>
答案 2 :(得分:0)
请忽略@RequestBody
注释,因为这仅适用于POST
次请求。
public String test2(@Valid TestClass req) {
return "test2";
}
答案 3 :(得分:0)
当您将控制器方法参数声明为@RequestBody
时,您希望它从请求正文中恢复,而不是作为常规&#34; http参数。
您可以尝试使用任何类型的Firefox(RESTClient)或Chrome(PostMan)插件,并尝试使用其中一个。你也可以使用SoapUI来做到这一点。
请求应该是POST
以这种方式请求的网址:
POST http://localhost:8080/test2
您必须提供能够提供预期Content-Type
和Accept
的http标头。如果使用Json,请将它们设置为:
Content-Type: application/json
Accept: text/html (As your method returns only a String)
然后将param写入请求正文。如果在Json中,就像这样:
{
"value":"the provided value"
}