SoFunction
Updated on 2025-03-08

Tutorial on using Spring Boot parameter verification and group verification

1. Introduction

One thing that is very annoying when doing web development is that it needs to verify the front-end input parameters. Basically, each interface needs to verify the parameters, such as some non-empty verification, format verification, etc. If there are fewer parameters, it is still easy to deal with. If there are more parameters, a large number of if-else statements will appear in the code.

Although using this method is simple and direct, there are also disadvantages. First, it reduces development efficiency, because the parameters we need to verify will exist in many places, and there will be repeated verifications in different places. Second, it reduces the readability of the code, because there is too much extra work code in the business code.

So we can use the validator component to perform unnecessary coding operations instead of us. This article is based on the introduction information of validator and also summarizes it based on my actual experience in the project. I hope it can help everyone.

1 What is validator

Bean Validation is a set of annotation-based data verification specifications defined by Java. It has been upgraded from version 1.0 of JSR 303 to version 1.1 of JSR 349, and then to version 2.0 of JSR 380 (2.0 was completed in 2017.08), and has experienced three versions. It should be noted that JSR is just a standard, which stipulates some specifications for verification annotation, but is not implemented, such as @Null, @NotNull, @Pattern, etc., which are located under this package. The hibernate validator is an implementation of this specification and adds some other verification annotations, such as @NotBlank, @NotEmpty, @Length, etc., which are located under this package.

If our project uses Spring Boot, the hibernate validator framework is already integrated in spring-boot-starter-web, so no need to add any other dependencies. If it is not a Spring Boot project, you need to add the following dependencies.

<dependency>
    <groupId></groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.</version>
</dependency>

2. Annotation introduction

1. Validator built-in annotations

annotation illustrate
@Null The annotated element must be null
@NotNull The annotated element cannot be null
@AssertTrue The annotated element must be true
@AssertFalse The annotated element must be false
@Min(value) The commented element must be a number, and its value must be greater than or equal to the specified minimum value.
@Max(value) The commented element must be a number, and its value must be less than or equal to the specified maximum value.
@DecimalMin(value) The commented element must be a number, and its value must be greater than or equal to the specified minimum value.
@DecimalMax(value) The commented element must be a number, and its value must be less than or equal to the specified maximum value.
@Size(max,min) The size of the annotated element must be within the specified range
@Digits(integer, fraction) The annotated element must be a number and its value must be within an acceptable range.
@Past The commented element must be a past date
@Future The commented element must be a future date
@Pattern(value) The annotated element must comply with the specified regular expression

The extension in hibernate validator defines the following annotations:

annotation illustrate
@NotBlank The annotated element cannot be null and must be greater than 0. It can only be used to annotate strings.
@Email The annotated element must be an email address
@Length(min=,max=) The commented string must be within the specified range
@NotEmpty The annotated element value is not null and not empty, and supports string, collection, map and array types.
@Range The annotated element must be within the specified range

3. Use

It is relatively simple to use, and it is all used with annotation. Specifically, it is divided into single-parameter verification and object parameter verification. Single-parameter verification means that the controller interface receives the front-end value according to single parameters, and does not have an encapsulated object for reception. If there is an encapsulated object, it is object parameter verification.

1 Single parameter verification

Single parameter verification only requires adding annotations before the parameters, as shown below:

public Result deleteUser(@NotNull(message = "id cannot be empty") Long id) {
  // do something
}

But one thing to note is that if you use single parameter verification, the @Validated annotation must be added to the controller class, as shown below:

@RestController
@RequestMapping("/user")
@Validated // Annotations required for single parameter verificationpublic class UserController {
  // do something
}

2 Object parameter verification

When using object parameter verification, you need to add annotation to the object's verification properties first, and then add an @Validated annotation before the object parameters of the Controller method, as shown below:

public Result addUser(@Validated UserAO userAo) {
    // do something
}

public class UserAO {
  @NotBlank
  private String name;

  @NotNull
  private Integer age;
  
  ……
}

Annotation grouping

In the object parameter verification scenario, there is a special scenario where the same parameter object has different verification rules in different scenarios. For example, when creating an object, you do not need to pass in the id field (the id field is the primary key, generated by the system, and not specified by the user), but when modifying the object, you must pass in the id field. In such a scenario, annotations need to be grouped.

1) The component has a default group, so we can create another group as shown below:

public interface UpdateAction {
}

2) To the attributes that need to be checked in the parameter class, add groups attributes to the annotation:

public class UserAO {

    @NotNull(groups = , message = "id cannot be empty")
    private Long id;
    
    @NotBlank
    private String name;

    @NotNull
    private Integer age;
    
    ……
}

As shown above, it means that the id field is only checked under the UpdateAction group, and the name field and the age field will be checked by default.

Then in the controller method, just specify which scenario in the @Validated annotation. If there is no specification, it means adoption. If other groups are used, the specification needs to be displayed. The following code indicates that parameters are checked according to the default in the addUser() interface, and parameters are checked according to the default in the updateUser() interface according to the default in the updateUser() interface.

public Result addUser(@Validated UserAO userAo) {
  // do something
}

public Result updateUser(@Validated({, }) UserAO userAo) {
  // do something
}

Object nesting

If there is an object attribute nested in the parameter object that needs to be checked, and the nested object attribute also needs to be checked, then you need to add the @Valid annotation to the object attribute.

public class UserAO {

    @NotNull(groups = , message = "id cannot be empty")
    private Long id;
    
    @NotBlank
    private String name;

    @NotNull
    private Integer age;
    
    @Valid
    private Phone phone;
    
    ……
}

public class Phone {
    @NotBlank
    private String operatorType;
    
    @NotBlank
    private String phoneNum;
}

3. Capture of error messages

An exception will be thrown after the parameter verification fails. We only need to catch the failed exception of the parameter verification in the global exception handling class, and then add the error message to the return value. The method of catching exceptions is as follows. The return value Result is a custom return value class our system has.

@RestControllerAdvice(basePackages= {"",""})
public class GlobalExceptionHandler {

  @ExceptionHandler(value = {})
  Result handleException(Throwable e, HttpServletRequest request){
    // Exception handling        }
}

It should be noted that if the exception thrown by missing parameters is MissingServletRequestParameterException, the exception thrown after the single parameter verification fails is ConstraintViolationException, the exception thrown after the object parameter verification failed is BindException, and the exception thrown after the object parameter verification failed is MethodArgumentNotValidException. Different exception objects have different structures, so the extraction method of exception messages is also different. As shown in the figure below:

1)MissingServletRequestParameterException

if(e instanceof MissingServletRequestParameterException){
    Result result = (ErrorCodeEnum.PARAM_ILLEGAL);
    String msg = ("Missing parameters{0}", ((MissingServletRequestParameterException) e).getParameterName());
    (msg);
    return result;
}

2) ConstraintViolationException exception

if(e instanceof ConstraintViolationException){
  // Single parameter verification abnormality  Result result = (ErrorCodeEnum.PARAM_ILLEGAL);
  Set&lt;ConstraintViolation&lt;?&gt;&gt; sets = ((ConstraintViolationException) e).getConstraintViolations();
  if((sets)){
    StringBuilder sb = new StringBuilder();
    (error -&gt; {
                    if (error instanceof FieldError) {
                        (((FieldError)error).getField()).append(":");
                    }
                    (()).append(";");
                });
    String msg = ();
    msg = (msg, 0, () -1);
    (msg);
  }
  return result;
}

3) BindException exception

if (e instanceof BindException){
      // The object parameter verification abnormality of get request      Result result = (ErrorCodeEnum.PARAM_ILLEGAL);
      List&lt;ObjectError&gt; errors = ((BindException) e).getBindingResult().getAllErrors();
      String msg = getValidExceptionMsg(errors);
      if ((msg)){
        (msg);
      }
      return result;
}

private String getValidExceptionMsg(List<ObjectError> errors) {
  if((errors)){
    StringBuilder sb = new StringBuilder();
    (error -> {
                    if (error instanceof FieldError) {
                       (((FieldError)error).getField()).append(":");
                    }
                    (()).append(";");
                });
    String msg = ();
    msg = (msg, 0, () -1);
    return msg;
  }
  return null;
}

4) MethodArgumentNotValidException

if (e instanceof MethodArgumentNotValidException){
      // The object parameter verification abnormality requested by post      Result result = (ErrorCodeEnum.PARAM_ILLEGAL);
      List&lt;ObjectError&gt; errors = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
      String msg = getValidExceptionMsg(errors);
      if ((msg)){
        (msg);
      }
      return result;
}

Summarize

This is the article about Spring Boot parameter verification and group verification. For more relevant Spring Boot parameter verification and group verification, please search for my previous articles or continue browsing the related articles below. I hope you will support me in the future!