【问题标题】:What is difference between @RequestBody and @RequestParam?@RequestBody 和 @RequestParam 有什么区别?
【发布时间】:2015-03-18 08:22:04
【问题描述】:

我通过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,并且默认注册了以下HttpMessageConverters:

...

但我的困惑是他们在文档中写的那句话是

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

这是什么意思?谁能给我一个例子?

spring doc中@RequestParam的定义是

表示方法参数应绑定到 Web 请求参数的注解。支持 ServletPortlet 环境中的带注释的处理程序方法。

我对他们感到困惑。请帮我举个例子说明它们之间的不同之处。

【问题讨论】:

  • @kryger 。这不是重复的,因为我有我的研究,我已经通过了春季文档。我已经要求提供示例。我已经给你定义了。我想举例说明它们之间有什么不同。上面的问题没有提供足够的解释,所以我认为它不应该被否决。

标签: spring spring-mvc spring-boot servlet-3.0 http-request-parameters


【解决方案1】:

@RequestParam 带注释的参数链接到特定的 Servlet 请求参数。参数值被转换为声明的方法参数类型。 此注解表示方法参数应绑定到 Web 请求参数。

例如,对 Spring RequestParam(s) 的 Angular 请求如下所示:

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

带有 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 带注释的参数链接到 HTTP 请求正文。使用 HttpMessageConverters 将参数值转换为声明的方法参数类型。 此注解表示方法参数应绑定到 Web 请求的正文。

例如,对 Spring RequestBody 的 Angular 请求如下所示:

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

带有 RequestBody 的端点:

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

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    映射HTTP请求头Content-Type,处理请求体。

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

    • @RequestBodyapplication/json,

    • @RequestPartmultipart/form-data,


    【讨论】:

    • 准确回答!不同的注解映射到不同的Web请求数据形式,由其“Content-Type”标头表示。
    【解决方案3】:

    @RequestParam 使 Spring 将请求参数从 GET/POST 请求映射到您的方法参数。

    GET 请求

    http://testwebaddress.com/getInformation.do?city=Sydney&country=Australia
    
    public String getCountryFactors(@RequestParam(value = "city") String city, 
                        @RequestParam(value = "country") String country){ }
    

    POST 请求

    @RequestBody 使 Spring 将整个请求映射到模型类,然后您可以从那里检索或设置其 getter 和 setter 方法的值。检查下面。

    http://testwebaddress.com/getInformation.do
    

    您有来自前端的 JSON 数据并命中您的控制器类

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

    Java 代码 - 后端 (@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;
        }
    }
    

    【讨论】:

      【解决方案4】:

      @RequestParam 注释告诉 Spring 它应该将请求参数从 GET/POST 请求映射到您的方法参数。例如:

      请求:

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

      端点代码:

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

      所以基本上,虽然@RequestBody 将整个用户请求(甚至对于 POST)映射到一个字符串变量,@RequestParam 使用一个(或多个 - 但更复杂的)请求参数到您的方法参数。

      【讨论】:

      • 请举例说明.@RequestBody
      【解决方案5】:

      这很简单,只要看看他们的名字@RequestParam 它由两部分组成,一个是“Request”,这意味着它将处理请求,另一部分是“Param”,它本身是有意义的,它只会映射对 java 对象的请求参数。 @RequestBody 的情况也是如此,它将处理随请求到达的数据,例如客户端是否发送了带有请求的 json 对象或 xml,此时必须使用 @requestbody。

      【讨论】:

        【解决方案6】:

        这里以@RequestBody为例,先看控制器!!

          public ResponseEntity<Void> postNewProductDto(@RequestBody NewProductDto newProductDto) {
        
           ...
                productService.registerProductDto(newProductDto);
                return new ResponseEntity<>(HttpStatus.CREATED);
           ....
        
        }
        

        这里是角度控制器

        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 ....
                                }
                        );
                    }
        

        简单看一下表格

         <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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-05
          • 2014-12-29
          • 1970-01-01
          • 1970-01-01
          • 2013-10-28
          • 2011-03-21
          • 1970-01-01
          相关资源
          最近更新 更多