This is the 25th day of my participation in the First Challenge 2022.

When writing logic in a project, it is necessary to evaluate various parameters to ensure the robustness of the program, which results in business code that is not only robust, but also bloated. SpringBoot already provides a Validation framework for parameters to verify their validity.

1. Introduce the Validation

Validation is a framework for checking the validity of parameters in your application code. It is integrated into the Spring-Context package as a Validation tool within the Spring framework.

1.1 the Validation annotations

Validation includes many annotations to help to check of Java program of different types of parameters, check of related annotation distribution in the spring – the boot – starter – Validation dependent javax.mail. Validation. The constraints in the package.

  • @null / @notnull, annotated fields must be Null/ must not be Null
  • @AssertFalse/@AssertTrue, the annotation field can be null, but must be false/true if it is not null
  • @email: The value of the annotated field must be in Email format
  • @URL, the field value of the annotation must be URL
  • @patten, annotated field values must conform to the defined regular expression

The use of other similar annotations can view javax.mail. Validation. Annotations defined constraints package information.

1.2 Difference between @ VALID and @validated

When using the Validation framework, it is common to misunderstand the use of the @VALID and @validated annotations. Here is a comparison of the two annotations.

  1. The function of the @validated and @valid annotations is the same when using only annotating field attributes and validating specifications.
  2. The Spring Validation framework provides the @Validated annotation to verify parameters, which conforms to Spring’s JSR-303 specification. The @VALID annotation is provided by Javax and conforms to the standard JSR-303 specification.
  3. In terms of annotations, the @Validated annotation can be used for types, methods, and parameters. And @valid can also be used for properties.
    / / @ Validated definitions
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interfaceValidated { Class<? >[] value()default {};
    }
    Copy the code
    / / @ Valid definition
    @Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    public @interface Valid {
    }
    Copy the code
  4. The @validated annotation can use the group verification function to provide different groups for the same object attribute and verify attribute parameters based on the group. The @VALID annotation does not support group validation.
  5. The @VALID annotation supports nested validation. When the property of a class is a complex object, you can use the @VALID annotation to verify the properties in the property object at the same time. @Validated is not supported on attributes.

2. Use the Validator in SpringBoot to verify parameters

2.1 Dependency Import

The use of validators in SpringBoot does not need to be imported separately because it already exists in web-dependent packages and can be used directly.

<! -- starter web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>Copy the code

If SpringBoot is a new version, the Validation framework may not be included in the Web package, and the Web dependency package for native SpringBoot version 2.6.3 is not included.or

The new version of SpringBoot is not included in the Web package, but it also provides the start dependency to provide related functions. The Jar package can be imported separately using the following coordinate information:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Copy the code

Alternatively, you can import the Validator framework package provided by Hibernate when introducing dependencies, but you need to indicate version number information when using it.

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1. 5.Final</version>
</dependency>
Copy the code

2.2 Annotation verification entity class

When receiving request parameters, the backend usually uses JavaBean objects to receive parameter information. If you want to validate attributes in an entity class, you need to annotate the attributes with validation-related annotations, and entity objects must define getter/setter methods, using @data of Lombok.

@Data
public class Customer{

    private Long id;
    
    @NotNull
    private String countryName;
    
    @NotNull
    private String countryCode;
    
    @Email
    private String email;
    
    @Valid
    private Customer parentCustomerInfo;
}
Copy the code

2.3 Enabling Parameter Verification

2.3.1 Simple Parameter Verification

Validation annotations can be used directly in method parameters when a service interface receives a single simple parameter.

@PostMapping("/get")
public ResultMap getCustomerInfo(@RequestParam("customerCode") @notnull (message = "User code cannot be empty!" ) String customerCode){
    return ResultMapUtils().ok();
}
Copy the code

The single-parameter verification takes effect only after the @ “Validated” mark is used in the controller class at the Controller layer.

2.3.2 JavaBean check

After the verification annotation is used to annotate the fields to be verified in the entity class, parameter verification needs to be enabled when the request layer receives parameters. You only need to use the @ “Validated” mark in the parameters of the Controller interface layer. When the interface receives request parameters, the verification will be performed automatically.

@Autowired
private CustomerService customerService;

@PostMapping("/execute")
public ResultMap execute(@RequestBody @Validated GeneralDataRequest<CustomerRequest> generalDataRequest){
    CustomerRequest request = generalDataRequest.getData();
    return customerService.execute(request);
}
Copy the code

2.4 Catch parameter verification exceptions

After using the Validation check abnormal, when the parameter when an exception occurs, throws MethodArgumentNotValidException type of exception, in order to program error is more easy to understand, you can define global to capture this type of anomaly, and unified returns the information.

@SLF4j
@ControllerAdvice
public class ExceptionConfig {
    /** * Parameter verification exception */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResultMap argumentExceptionHandler(MethodArgumentNotValidException exception) {
        String message = exception.getBindingResult().getFieldError().getDefaultMessage();
        log.info(Parameter exception occurred :{}, message);
        return ResultMapUtils.resultError(ErrorCodeConstant.System.E100003, null, message); }}Copy the code