@ RequestBody 和@RequestParam 有什么区别?

我通过 Spring 文档了解了 @RequestBody,他们给出了以下解释:

@RequestBody方法参数注释表明方法参数应该绑定到 HTTP 请求体的值。例如:

@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
writer.write(body);
}

可以使用 HttpMessageConverter将请求体转换为方法参数。HttpMessageConverter负责将 HTTP 请求消息转换为对象,并将对象转换为 HTTP 响应主体。

DispatcherServlet支持使用 DefaultAnnotationHandlerMappingAnnotationMethodHandlerAdapter进行基于注释的处理。在 Spring 3.0中,AnnotationMethodHandlerAdapter被扩展为支持 @RequestBody,并且默认注册了以下 HttpMessageConverter:

...

但我的困惑是他们在文件里写的那句话

@ RequestBody 方法参数注释表明方法参数应该绑定到 HTTP 请求体的值。

他们是什么意思? 谁能给我举个例子?

春季文档中的 @RequestParam定义是

注释,指示方法参数应该绑定到 web 请求参数。在 ServletPortlet环境中支持带注释的处理程序方法。

我对他们之间的区别感到困惑。请给我举个例子,说明他们之间是如何不同的。

177540 次浏览

@RequestParam annotation tells Spring that it should map a request parameter from the GET/POST request to your method argument. For example:

request:

GET: http://someserver.org/path?name=John&surname=Smith

endpoint code:

public User getUser(@RequestParam(value = "name") String name,
@RequestParam(value = "surname") String surname){
...
}

So basically, while @RequestBody maps entire user request (even for POST) to a String variable, @RequestParam does so with one (or more - but it is more complicated) request param to your method argument.

@RequestParam annotated parameters get linked to specific Servlet request parameters. Parameter values are converted to the declared method argument type. This annotation indicates that a method parameter should be bound to a web request parameter.

For example Angular request for Spring RequestParam(s) would look like that:

$http.post('http://localhost:7777/scan/l/register?username="Johny"&password="123123"&auth=true')
.success(function (data, status, headers, config) {
...
})

Endpoint with RequestParam:

@RequestMapping(method = RequestMethod.POST, value = "/register")
public Map<String, String> register(Model uiModel,
@RequestParam String username,
@RequestParam String password,
@RequestParam boolean auth,
HttpServletRequest httpServletRequest) {...

@RequestBody annotated parameters get linked to the HTTP request body. Parameter values are converted to the declared method argument type using HttpMessageConverters. This annotation indicates a method parameter should be bound to the body of the web request.

For example Angular request for Spring RequestBody would look like that:

$scope.user = {
username: "foo",
auth: true,
password: "bar"
};
$http.post('http://localhost:7777/scan/l/register', $scope.user).
success(function (data, status, headers, config) {
...
})

Endpoint with RequestBody:

@RequestMapping(method = RequestMethod.POST, produces = "application/json",
value = "/register")
public Map<String, String> register(Model uiModel,
@RequestBody User user,
HttpServletRequest httpServletRequest) {...

Hope this helps.

Here is an example with @RequestBody, First look at the controller !!

  public ResponseEntity<Void> postNewProductDto(@RequestBody NewProductDto newProductDto) {


...
productService.registerProductDto(newProductDto);
return new ResponseEntity<>(HttpStatus.CREATED);
....


}

And here is angular controller

function postNewProductDto() {
var url = "/admin/products/newItem";
$http.post(url, vm.newProductDto).then(function () {
//other things go here...
vm.newProductMessage = "Product successful registered";
}
,
function (errResponse) {
//handling errors ....
}
);
}

And a short look at form

 <label>Name: </label>
<input ng-model="vm.newProductDto.name" />


<label>Price </label>
<input ng-model="vm.newProductDto.price"/>


<label>Quantity </label>
<input ng-model="vm.newProductDto.quantity"/>


<label>Image </label>
<input ng-model="vm.newProductDto.photo"/>


<Button ng-click="vm.postNewProductDto()" >Insert Item</Button>


<label > \{\{vm.newProductMessage}} </label>

@RequestParam makes Spring to map request parameters from the GET/POST request to your method argument.

GET Request

http://testwebaddress.com/getInformation.do?city=Sydney&country=Australia


public String getCountryFactors(@RequestParam(value = "city") String city,
@RequestParam(value = "country") String country){ }

POST Request

@RequestBody makes Spring to map entire request to a model class and from there you can retrieve or set values from its getter and setter methods. Check below.

http://testwebaddress.com/getInformation.do

You have JSON data as such coming from the front end and hits your controller class

{
"city": "Sydney",
"country": "Australia"
}

Java Code - backend (@RequestBody)

public String getCountryFactors(@RequestBody Country countryFacts)
{
countryFacts.getCity();
countryFacts.getCountry();
}




public class Country {


private String city;
private String country;


public String getCity() {
return city;
}


public void setCity(String city) {
this.city = city;
}


public String getCountry() {
return country;
}


public void setCountry(String country) {
this.country = country;
}
}

map HTTP request header Content-Type, handle request body.

  • @RequestParamapplication/x-www-form-urlencoded,

  • @RequestBodyapplication/json,

  • @RequestPartmultipart/form-data,


It is very simple just look at their names @RequestParam it consist of two parts one is "Request" which means it is going to deal with request and other part is "Param" which itself makes sense it is going to map only the parameters of requests to java objects. Same is the case with @RequestBody it is going to deal with the data that has been arrived with request like if client has send json object or xml with request at that time @requestbody must be used.