The @ RequestParam Object Binding Method of Spring

  • 2021-12-04 10:12:49
  • OfStack

Directory Spring @ RequestParam Object Binding Solution Verify Request Parameters in POJO SpringMvc Parameter Binding Custom Object json Submission form Submission Summary 1

Spring @ RequestParam Object Binding

In Spring, using @ RequestParam to annotate multiple parameters in the method parameter list makes the mapping method much less readable.

Using @ RequestParam is very intuitive if the mapping request has only one or two parameters, but it is easy to get dizzy if the parameter list is getting longer and longer.

Solutions

You can use the ParameterObject schema directly to handle "Note: ParameterObject is to assemble parameters into objects".

If you want to pass a parameter to the database operation, the parameter corresponds to some fields in the database, and the entity object corresponding to the table can be directly used as ParameterObject.

In other cases, you can wrap these parameters with an POJO, which itself requires no additional annotations, but the POJO itself must contain fields that exactly match the requested parameters, the standard setter/getter, and a constructor without arguments:


class ProductCriteria {
   private String query;
   private int offset;
   private int limit;
   ProductCriteria() {
   }
   public String getQuery() {
       return query;
   }
   public void setQuery(String query) {
       this.query = query;
   }
   // other getters/setters
}
@GetMapping
List<Product> searchProducts(ProductCriteria productCriteria) {
   return productRepository.search(productCriteria);
}

Verify the request parameters in POJO

Although the above case can be used normally, we know that using @ RequestParam annotation is not only for binding request parameters, but also a very important function is that we can request verification for bound parameters, such as whether the parameters are necessary or not, and if the parameters are missing from the request, our server can reject the request.

Want to add validation rules for the fields in our POJO. If you want to mimic the performance of @ RequestParam (required = false), you can use the @ NotNull annotation on the corresponding field.

In more cases, we generally use @ NotBlank than @ NotNull, because @ NotBlank takes into account empty strings.


final class ProductCriteria {
   @NotBlank
   private String query;
   @Min(0)
   private int offset;
   @Min(1)
   private int limi;
   // ...
}

One point must be noted here:

It is not enough to just add validation comments to the fields of objects.

1 Be sure to add @ Valid annotation before the corresponding parameter of POJO in the method parameter package of controller. This annotation causes Spring to perform validation actions before binding parameters.


@GetMapping
List<Product> searchProducts(@Valid ProductCriteria productCriteria) {
   // ...
}

Another very useful feature of the @ RequestParam annotation is setting default values for parameters.

If we use POJO to bind parameters, we only need to set the default value of the field when defining parameters. If the parameter is not in the request, Spring does not override the default value of the parameter to null's.

SpringMvc parameter binding custom object

springmvc We often accept two ways when writing controller1, one is form submission and the other is json submission. Here is how to automatically bind submitted data to custom objects in these two ways.

json Commit

This is relatively simple, search 1 on the Internet, and simply put 1 code here:


@RequestMapping("/testjson")
public String testjson(@RequestBody User user){
    return "ok";
}

form Commit

This is a headache. 1 form has many parameters. We can write as follows:


@RequestMapping("/test")
public String testParam(@RequestParam(name = "name") String name, @RequestParam(name = "sex") String sex) {
    return name + sex;
}

But what happens if I change to the following? Then submit the parameter name=zack with form & sex=boy


@RequestMapping("/test")
public String test(@RequestParam(name = "user") User user) {
    return user.getName();
}

The result is an error:

{
"timestamp": "2018-05-29T11:58:37.450+0000",
"status": 400,
"error": "Bad Request",
"message": "Required User parameter 'user' is not present",
"path": "/test1"
}

There is really no user in my parameters. In fact, my original purpose is to make spring familiar with assembling name and sex I passed to generate an user object, because user object just has these two attributes, but spring has no intelligence. So what should I do?

Introduce WebDataBinder at this time, and add the following code to your controller:


@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(User.class, new UserFormatEditor());
}
public static class UserFormatEditor extends PropertiesEditor {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(JSONObject.parseObject(text, User.class));
    }
    @Override
    public String getAsText() {
        return getValue().toString();
    }
}

Then change the parameters to user = {"name": "zack", "sex": "boy"} when requesting, and then successfully get the User object. WebDataBinder tells spring for us. If we encounter a string parameter to be wrapped as User. class, just use our custom UserFormatEditor.

Summary 1

As a specification, the submission method of form itself requires us to receive one attribute, but cannot receive it with one object system 1. If you want to receive it with one object system 1, please submit it with json.


Related articles: