SoFunction
Updated on 2025-03-08

Spring Validation interface parameter verification sample code

1. Preface

JSR is the abbreviation of Java Specification Requests, which means JAVA specification proposal.

JSR 303 - Bean Validation specification is a set of standards based on JavaBean parameter verification.

Hibernate Validator is an implementation of JSR 303. It provides implementation of all constraints in the JSR 303 specification, and also makes some expansions to it.

Spring Validation is a secondary package of Hibernate validation to support Spring MVC parameter verification.

😊 JSR 303 contains annotations:

Verification Notes

Verify data type

illustrate

@Null

Any type

The element value is Null

@NotNull

Any type

The element value is not Null

@AssertTrue

Bool

The element is true

@AssertFalse

Bool

The element is false

@Min(value = minimum value)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value must be greater than or equal to the specified value

@Max(value = maximum value)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value must be less than or equal to the specified value

@DecimalMin(value = minimum value)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value must be greater than or equal to the specified value

@DecimalMax(value = maximum value)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value must be less than or equal to the specified value

@Size(min = minimum value, max = maximum value)

String, Collection, Array, etc.

The character length/set size of the element value must be within the specified interval range.

@Digits(integer = integer digits, fraction = decimal digits)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value integer and decimal places must be less than the corresponding specified value

@Past

DATE, Calendar, Time, etc.

The element value must be before the specified time

@Future

DATE, Calendar, Time, etc.

The element value must be after the specified time

@Pattern(regexp = regular, flag = pattern)

String etc.

The element value matches the specified regularity

😊 Extended notes:

Verification Notes

Verify data type

illustrate

@NotBlank

String, etc. CharSequence subtypes

The element value is not an empty string (the string is not Null and the length is not 0 after removing the beginning and end spaces)

@Email(regexp = regular, flag = pattern)

String etc.

The element value is in the email format, and the format can be specified through the regexp and flag attributes.

@Length(min = minimum value, max = maximum value)

String etc.

The element value length is within the specified interval range

@NotEmpty

String, Collection, Array, etc.

The element value is not Null and the length is not 0

@Range(min = minimum value, max = maximum value)

BigDecimal, BigInteger, byte, short, int, long, etc. Number or CharSequence (number) subtypes

The element value is within the specified interval range

@URL

String etc.

The URL that is legal when the element value must be

2. Use of Spring Validation

1. Introduce dependencies in the project

<!-- JSR 303 -->
<dependency>
    <groupId></groupId>
    <artifactId>validation-api</artifactId>
</dependency>
<!-- exist SpringBoot In the project,like SpringBoot Version smaller than 2. ,则此依赖已包含exist spring-boot-starter-web middle,No need to add additional dependencies;
like SpringBoot Version greater than 2. ,You need to manually introduce dependencies。-->
<!-- Hibernate Validator -->
<dependency>
    <groupId></groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

2. Use scenarios for parameter annotation verification

Scenario 1: Verification of direct entry parameters

① Add @Validated annotation to the class, otherwise the parameter verification will not take effect;

② Use annotations @NotEmpty, etc. in the parameter;

@Validated
@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/saveUserName")
    public String saveUserInfo(@NotEmpty String userName) {
        ("userName:"+ userName +", save successfully");
        return "success";
    }
}

test:

【Request URL】:
http://192.168.1.7:27100/user/saveUserName?userName=
 
【Execution Results】:
Critical: () for servlet [dispatcherServlet] in context with path [] throw exception [Request processing failed; nested exception is : : Cannot be empty] with root cause
: : Can't be empty
    at (:116)
    at (:186)
    at $(:688)
……

Scenario 2: Verification of object model attributes

1. Create User object

@Data
public class User {
    private Integer id;
    @NotEmpty(message = "Username cannot be empty")
    private String userName;
    private Integer age;
    @NotNull(message = "User password cannot be empty")
    @Size(min = 5, max = 10,message = "The password must be 5-10 characters")
    private String password;
}

2. Global exception capture

@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
      * Methods are directly entered into the parameter verification
      *
      * @param ex
      * @return
      */
    @ExceptionHandler()
    public BaseResult resolveConstraintViolationException(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ();
        if (!(constraintViolations)) {
            String errorMessage = ().map(ConstraintViolation::getMessage).collect((", "));
            return (ResultEnum.ILLEGAL_PARAMETER, errorMessage);
        }
        return (ResultEnum.ILLEGAL_PARAMETER, ());
    }
    /**
      * Object model attribute verification
      *
      * @param ex
      * @return
      */
    @ExceptionHandler()
    public BaseResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        List<ObjectError> allErrors = ().getAllErrors();
        if (!(allErrors)) {
            String errorMessage = ().map(ObjectError::getDefaultMessage).collect((", "));
            return (ResultEnum.ILLEGAL_PARAMETER, errorMessage);
        }
        return (ResultEnum.ILLEGAL_PARAMETER, ());
    }
}

3. General return structure

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class BaseResult<T> {
    private Integer code;
    private String message;
    private T data;
    public static <T> BaseResult<T> success() {
        return new BaseResult((), (), new JSONObject());
    }
    public static <T> BaseResult<T> fail(ResultEnum resultEnum, T data) {
        return fail((), (), data);
    }
    @Override
    public String toString() {
        return "BaseResult{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

4. Error prompt code enumeration class

/**
  * Error prompt code
  */
public enum ResultEnum {
    /** Status code: Unknown error **/
    UNKNOWN_ERROR(-1, "Unknown Error"),
    /** Status Code: Success **/
    SUCCESS(0, "success"),
    /** Status Code: Failed **/
    FAIL(1,"fail"),
    /** Status code: Illegal parameter **/
    ILLEGAL_PARAMETER(2,"Illegal Parameters");
    private Integer code;
    private String msg;
    ResultEnum(Integer code, String msg) {
         = code;
         = msg;
    }
    public Integer getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

5. Exposed interface

① Add @Validated annotation to the class, otherwise the parameter verification will not take effect;

② Add @Validated annotation before entering the parameter entity;

@Validated
@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/saveUserInfo")
    public String saveUserInfo(@RequestBody @Validated User user) {
        ("userName:"+ () +", save successfully");
        return "success";
    }
}

6. Test:

【Request URL】: http://192.168.1.7:27100/user/saveUserInfo
【Request method】: POST
【Request Parameters】:
{
"userName":"Zhang San"
}
 
【Execution Results】:
{
     "code": 2,
"message": "Illegal parameter",
"data": "User password cannot be empty"
}

Scenario 3: Group verification of parameter annotation verification

1. Create a new packet interface

/**
  * Packet interface: added
  */
public interface Add {
}
/**
  * Packet interface: Updated
  */
public interface Update {
}

2. Use the groups attribute to indicate grouping in verification annotation

@Data
public class User {
 
    @NotNull(message = "When updating data, the primary key id cannot be empty", groups = )
    private Integer id;
 
    @NotEmpty(message = "Username cannot be empty")
    private String userName;
    
    private Integer age;
 
    @NotNull(message = "User password cannot be empty")
    @Size(min = 5, max = 10,message = "The password must be 5-10 characters")
    private String password;
}

[Note] It should be noted that all field annotation verification rules in the entity class belong to the Default group by default, and the interface parameter @Validated annotation default verification rules for verifying the Default group. When an interface parameter uses @Validated to explicitly declare non-default grouping, all annotation checks in the entity class that do not explicitly declare the grouping will not take effect.

3. Processor method

@Validated
@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/updateUserInfo")
    public String updateUserInfo(@RequestBody @Validated({}) User user) {
        ("id:" + () + ",userName:"+ () +", update succeeded");
        return "success";
    }
}

4. Test

【Request URL】: http://192.168.1.7:27100/user/updateUserInfo
【Request method】: POST
【Request Parameters】:
{
  "id":1,
"userName":"Li Si"
}
 
【Execution Results】:
id:1, userName: Li Si, updated successfully

[Note] There is no "password" passed in the parameter, and there is no verification. If the fields that belong to the Default group by default also need to be checked, it can be written as:

public String updateUserInfo(@RequestBody @Validated({, }) User user) {

Scenario 4: Cascade verification

1. In the entity class model, there may be member variables of set type or entity type, and the fields in this member still need to be checked.

Use @Valid annotation on the property/list of the object type to be verified:

@Data
public class User {
    @NotNull(message = "When updating data, the primary key id cannot be empty", groups = )
    private Integer id;
    @NotEmpty(message = "Username cannot be empty")
    private String userName;
    private Integer age;
    @NotNull(message = "User password cannot be empty")
    @Size(min = 5, max = 10,message = "The password must be 5-10 characters")
    private String password;
    @Valid
    private List&lt;Car&gt; cars;
}
@Data
public class Car {
    @NotNull(message = "The license plate number cannot be empty")
    private String plateCode; 
    @NotNull(message = "The license plate color cannot be empty")
    private String plateColor;
}

2. Processor method

@Validated
@RestController
@RequestMapping("/user")
public class UserController {
    @PostMapping("/saveUserInfo")
    public String saveUserInfo(@RequestBody @Validated User user) {
        ("userName:"+ () +", save successfully");
        return "success";
    }
}

3. Test

【Request URL】: http://192.168.1.7:27100/user/saveUserInfo
【Request method】: POST
【Request Parameters】:
{
"userName": "Li Si",
    "password": "123456",
    "cars": [
        {
"plateCode": "Beijing A0001",
            "plateColor": "1"
        },
                {
"plateCode": "Beijing A0002"
        }
    ]
}
【Execution Results】:
{
     "code": 2,
"message": "Illegal parameter",
"data": "The license plate color cannot be empty"
}

Scene 5: Custom annotation verification

As follows: Check the user's license plate number must contain "Beijing A", otherwise the prompt will be returned;

1. Custom comments

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {})
public @interface MustContainKey {
    //Default error message    String message() default "Must contain specified keywords";
   //Group    Class&lt;?&gt;[] groups() default {};
    // Load    Class&lt;? extends Payload&gt;[] payload() default {};
}

2. The real verification class implements the ConstraintValidator interface

public class MustContainKeyValidator implements ConstraintValidator&lt;MustContainKey,String&gt; {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (!(value) &amp;&amp; !("Beijing A")) {
            // Get the default prompt message            String defaultConstraintMessageTemplate = ();
            (defaultConstraintMessageTemplate);
            // Disable default prompt information            // ();
            //Setting prompt            // ("must contain key").addConstraintViolation();
            return false;
        }
        return true;
    }
}

3. Add this comment to the properties of the entity class

@Data
public class User {
    @NotNull(message = "When updating data, the primary key id cannot be empty", groups = )
    private Integer id;
    @NotEmpty(message = "Username cannot be empty")
    private String userName;
    private Integer age;
    @NotNull(message = "User password cannot be empty")
    @Size(min = 5, max = 10,message = "The password must be 5-10 characters")
    private String password;
    @Valid
    private List&lt;Car&gt; cars;
}
@Data
public class Car {
    @MustContainKey
    @NotNull(message = "The license plate number cannot be empty")
    private String plateCode; 
    @NotNull(message = "The license plate color cannot be empty")
    private String plateColor;
}

4. Test

【Request URL】: http://192.168.1.7:27100/user/saveUserInfo
【Request method】: POST
【Request Parameters】:
{
        
"userName": "Li Si",
    "password": "123456",
    "cars": [
        {
"plateCode": "Beijing A0001",
            "plateColor": "1"
        },
        {
"plateCode": "Zhe C0002",
            "plateColor": "2"
        }
    ]
}
【Execution Results】:
{
     "code": 2,
"message": "Illegal parameter",
"data": "must contain specified keywords"
}

The above is all about Spring Validation!

Summarize

This is the end of this article about Spring Validation interface parameter verification. For more relevant Spring Validation interface parameter verification content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!