Detailed Spring parameter validation differences between @Validated and @Valid

  • 2021-06-28 09:16:42
  • OfStack

The Spring Validation validation framework provides @Validated (the Spring's JSR-303 specification, a variant of the standard JSR-303) for the validation mechanism of parameters. javax provides @Valid (the standard JSR-303 specification) for direct parameter validation results in conjunction with BindingResult.Specific validation notes for fields, such as @NotNull, are available all over the Web and are not detailed here.

There is not much difference in basic validation functionality between @Validated or @Valid when checking whether Controller's entry meets the specification.But there are two differences in grouping, annotation places, nested validation, and so on:

1. Grouping

@Validated: Provides a grouping function that allows you to use different authentication mechanisms for different groupings when participating in validation. There is also information on this web, not detailed. @Valid: As a standard JSR-303 specification, grouping has not yet been absorbed.

2. Note Places

@Validated: Can be used on type, method, and method parameters.But it cannot be used on member properties (fields)

@Valid: Can be used on methods, constructors, method parameters, and member properties (fields)

Whether they can be used on member attributes (fields) directly affects the ability to provide nested validation.

3. Nested Validation

When comparing the two nested validations, first explain what is called nested validation.For example, we now have an entity called Item:


public class Item {

  @NotNull(message = "id Cannot be empty ")
  @Min(value = 1, message = "id Must be a positive integer ")
  private Long id;

  @NotNull(message = "props Cannot be empty ")
  @Size(min = 1, message = " At least one 1 Attributes ")
  private List<Prop> props;
}

Item has many attributes, including attribute id, attribute value id, attribute name and attribute value, as follows:


public class Prop {

  @NotNull(message = "pid Cannot be empty ")
  @Min(value = 1, message = "pid Must be a positive integer ")
  private Long pid;

  @NotNull(message = "vid Cannot be empty ")
  @Min(value = 1, message = "vid Must be a positive integer ")
  private Long vid;

  @NotBlank(message = "pidName Cannot be empty ")
  private String pidName;

  @NotBlank(message = "vidName Cannot be empty ")
  private String vidName;
}

Attribute is also an entity that has its own validation mechanism, such as attribute and attribute value id cannot be empty, attribute name and attribute value cannot be empty, and so on.

Now that we have an ItemController that accepts an Item, we want to validate the Item as follows:


@RestController
public class ItemController {

  @RequestMapping("/item/add")
  public void addItem(@Validated Item item, BindingResult bindingResult) {
    doSomething();
  }
}

In the figure above, if the props attribute of the Item entity is not commented on, only @NotNull and @Size, the Spring Validation framework only validates id and props of Item, not null and quantitative, and does not validate Prop entities in the props field, that is, @Validated and @Valid before the method parameters.Nested validation of parameters is not automatically performed.That is, if List is passed < Prop > pid with Prop is null or negative and will not be detected by enrollment validation.

To be able to nest validation, you must manually specify on the props field of the Item entity that the entities in this field are also validated.Since @Validated cannot be used on member attributes (fields), but @Valid can be added on member attributes (fields), and the @Valid class annotation indicates that it supports nested validation, we can infer that @Valid cannot be added to a method parameter automatically for nested validation, but is used on the corresponding fields that require nested validation classes.To do nested validation with @Validated or @Valid on the method parameter.

We modified the Item class as follows:


public class Item {

  @NotNull(message = "id Cannot be empty ")
  @Min(value = 1, message = "id Must be a positive integer ")
  private Long id;

  @Valid //  Nested validation must use @Valid
  @NotNull(message = "props Cannot be empty ")
  @Size(min = 1, message = "props At least one 1 Custom Properties ")
  private List<Prop> props;
}

Then we can use @Validated or @Valid on ItemController's addItem function to nest validation of Item's entry.If the corresponding field containing Prop in Item is empty, the Spring Validation framework will detect it and bindingResult will record the corresponding error.

Summarize the differences between @Validated and @Valid in nested validation capabilities:

@Validated: Nested validation cannot be provided separately on method entry.It cannot be used on member properties (fields) or prompt the framework for nested validation.Can be used with nested validation annotation @Valid for nested validation.

@Valid: Nested validation cannot be provided separately on method entry.Can be used on member properties (fields) to prompt the validation framework for nested validation.Can be used with nested validation annotation @Valid for nested validation.


Related articles: