The difference between @RequestParam, @ModelAttribute, and @RequestBody

One, @RequestParam

@PostMapping("/getUserLogin") 
public String getUserLogin(@RequestParam("username") String username,
@RequestParam("password") String password) { 
    selectByCond(username,password);
}

Note: If @RequestParam(xxx) is written before the parameter, the front end must have the corresponding xxx name (regardless of whether it has a value, of course, you can adjust whether it must be passed by setting the required attribute of the annotation), if there is no xxx name If this is the case, then the request will go wrong, and 400 will be reported.

Note: If @RequestParam(xxx) is not written before the parameter, then the front end can have no corresponding xxx name. If there is xxx name, then it will automatically match; if not, the request can be sent correctly.

Note: This is different from when feign consumes services; when feign consumes services, if nothing is written before the parameters, it will be @RequestBody by default.

When using @RequestParam() and @RequestBody at the same time, the parameters specified by @RequestParam() can be ordinary elements, arrays, collections, objects, etc.

Two, @ModelAttribute

@PostMapping("/getUserLogin") 
public String getUserLogin(@ModelAttribute UserLogin userLogin) { 
    String username = userLogin.getUsername;
    String password = userLogin.getPassword;
    selectByCond(username,password);
}

1. @ModelAttribute can be annotated on the method, the @ModelAttribute method is called before the controller method annotated with @RequestMapping is called.

2. When used as method parameters, the indicated parameters should be retrieved from the model. If it does not exist, it should be instantiated first and then added to the model. Once it appears in the model, the parameter field should be populated from all request parameters with matching names.

Three, the difference between @RequestParam and @ModelAttribute

  1. @ModelAttribute: Bind the entire Java object (such as Employee). Support multiple request parameters
  2. @RequestParam: Combine a single request parameter (like firstName)
  3. @RequestParam is most suitable for reading a small params.
  4. @ModelAttribute is used for forms with a large number of fields.
  5. @ModelAttribute provides you with additional features such as data binding, validation and form pre-filling.
  6. When using @RequestParam() and @RequestBody at the same time, the parameters specified by @RequestParam() can be ordinary elements, arrays, collections, objects, etc.

四、@RequestBody

1. Introduction to @RequestBody

@RequestBody is mainly used to receive the data in the json string passed from the front end to the back end (data in the request body);

@RequestBody is used for post requests, not for get requests.

Note: A request has only one RequestBody; a request can have multiple RequestParams.

Note: When using @RequestParam() and @RequestBody at the same time, the parameters specified by @RequestParam() can be ordinary elements, arrays, collections, objects, etc. (ie: when @RequestBody and @RequestParam() can be used at the same time, The original SpringMVC mechanism for receiving parameters remains unchanged, except that RequestBody receives the data in the request body; and RequestParam receives the parameters in the key-value , so it will be processed by the aspect so that ordinary elements, arrays, collections, etc. can be used. Subject, etc.).

That is: if the parameter is placed in the request body, and application/json is passed to the background, the background can only receive it with @RequestBody;

If it is not in the request body, then when the background receives the parameters from the foreground, it must be received with @RequestParam, or it can be received without writing anything before the formal parameters.

If the back-end parameter is an object, and the parameter is modified with @RequestBody, then the front-end must meet the following requirements when passing the json parameter:

  1. When the class corresponding to the backend @RequestBody annotation assembles the HTTP input stream (including the request body) to the target class (ie: the class after @RequestBody), it will match the attributes of the corresponding entity class according to the key in the json string. If the match is consistent and the value corresponding to the key in json meets (or can be converted to), when the type requirement of the corresponding property of the entity class is required, the setter method of the entity class will be called to assign the value to the property.
  2. In the json string, if the value is "", if the back-end corresponding attribute is of type String, then the received is "", if the back-end attribute is of type Integer, Double, etc., then the received is null .
  3. In the json string, if the value is null, the backend correspondingly receives null.
  4. If a parameter does not have a value, when passing the json string to the backend, the field must not be written to the json string at all; or when writing the value, there must be a value, null or "" will do.

2. Incoming list

@GetMapping("/getUserLogin")
public String getUserLogin(@RequestBody UserLogin userLogin, 
@RequestParam("arrays") List<String> arrays){
    StringBuilder sb = new StringBuilder();
    for(String array : arrays){
        sb.append(array);
        sb.append(",");
    }
    return sb + "," +  userLogin;
}

3. Core logic analysis

Example of core logic analysis when @RequestBody accepts json

Suppose the json string passed by the front end is like this: {"name1":"素小暖","age":18} The  backend model only has the name and age attributes, and the corresponding setter/getter methods; the general used ones are given The core logic of deserializeFromObject(JsonParser p, DeserializationContext ctxt) method:

//前提是前端传入的是json数据
//@JsonAlias表示当进行前端接口调用的时候,user中username传入"userName","userName","UserName"都可接收
//@JsonProperty表示只能传入passWord,password都无法进行调用
@Data
public class User{
    @JsonAlias(value={"userName","userName","UserName"})
    private String username;
    @JsonProperty(value="passWord")
    private String password;
}

@PostMapping("/getUserLogin")
public User getUserLogin(@RequestBody User user){
    ...
}

 note:

  1. The @JsonAlias ​​annotation needs to depend on the setter and getter, while the @JsonProperty annotation does not.
  2. Without considering the above two annotations, the default case is sensitive when the key matches the attribute.
  3. In a json string with multiple same keys, when converted to a model, the value of the last key among the same keys will be copied to the model attribute because the setter will overwrite the original value.
  4. When the back-end @RequestBody annotation corresponds to the class when assembling the HTTP input stream (including the request body) to the target (ie: the class after @RequestBody), it will match the attributes of the corresponding entity class according to the key in the json string, if When the match is consistent and the value corresponding to the key in json meets (or can be converted to) the type requirement of the corresponding property of the entity class, the setter method of the entity class will be called to assign the value to the property.

 

Previous: [Summary of the most complete Java framework in the full stack] SSH, SSM, Springboot

Next article: SpringCloud learning general outline

Guess you like

Origin blog.csdn.net/guorui_java/article/details/112295474