[Spring Boot] Web Development - Data Validation

Web Development - Data Validation

For the application system, any data sent by the client is not absolutely safe and effective, which requires us to verify the validity of the data when the server receives the data to ensure that the incoming data is safe and correct. Next, we will introduce how Spring Boot implements data validation.

1. Introduction to Hibernate Validator

Data validation is an important part of Web development. Currently, there are many specifications and components for data validation, including JSR-303/JSR-349, Hibernate Validator, and Spring Validation.

  • The JSR (Java Specification Request) specification is a sub-specification in Java EE 6, also known as Bean Validation. It specifies a set of bean-based validation APIs, adding constraints to object properties through annotations.
  • Hibernate Validator is an implementation of the JSR specification and adds some other validation annotations, such as @Email, @Length, @Range, etc.
  • Spring Validation is Spring's second package of Hibernate Validator in order to provide convenience for developers. At the same time, Spring Validation adds automatic verification to the SpringMVC module and encapsulates the verification information into a specific class.

JSR defines the data validation specification, and Hibernate Validator is based on the JSR specification, implementing various data validation annotations and some additional constraint annotations. Spring Validation is the encapsulation and integration of Hibernate Validator. Commonly used annotations in JSR and Hibernate Validator are shown in the table.

insert image description here
The table contains the validation annotations defined by JSR-303 implemented by Hibernate Validator and the validation annotations defined by Hibernate Validator itself, and also supports custom constraint annotations. All annotations contain two attributes, code and message.

  • Message defines the error message when the data verification fails.
  • code defines the wrong type.

Spring Boot is developed from Spring, so it naturally supports Hibernate Validator and Spring Validation, and the Hibernate Validator component is used by default.

2. Data verification

Using Hibernate Validator to verify data requires defining a received data model, and using annotations to describe the rules of field verification. The following uses the User object as an example to demonstrate how to use Hibernate Validator to verify data.

2.1 JavaBean parameter verification

When there are many parameters in the Post request, data verification can be performed in the corresponding data model (Java Bean), and the rules for field verification can be specified through annotations. The following is a demonstration with specific examples. First, create a Java Bean entity class:

public class User {
    
    
    @NotBlank(message = "姓名不允许为空!")
    @Length(min = 2, max = 1,message = "姓名长度错误,姓名长度2-10!")
    private String name;

    @NotNull(message ="年龄不能为空!")
    @Min(18)
    private int age;

    @NotBlank(message ="地址不能为空!")
    private String address;

    @Pattern(regexp = "((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
    private String phone;

    @Email(message ="邮箱格式错误")
    private String email;

    //省略get和set方法
}

In the example, the attribute message in each annotation is the prompt message to be given when the data verification fails, such as @Email(message="Email format error"), when the mail format verification fails, prompt the mail format mistake. Then, add a data validation method:

    @PostMapping(path ="/check")
    public String check(@RequestBody @Valid User user, BindingResult result) {
    
    
        String name = user.getName();
        if(result.hasErrors()) {
    
    
            List<ObjectError> list = result.getAllErrors();
            for (ObjectError error : list) {
    
    
                System.out.println(error.getCode() + "_" + error.getDefaultMessage());
            }
        }
        return name;
    }

In the above example, the @Valid annotation is added after the @RequestBody annotation, and then BindingResult is added to return the verification result. BindingResult is the result set when the verification fails.

Note that BindingResult must follow the parameter to be verified. If there is no BindingResult object after the parameter to be verified, BindException will be thrown.

Finally, run validation.

Start the project, request the /user/check interface in postman, and the data verification result is output in the background:

Length-密码长度错误,密码长度6-20!
Min-最小不能小于18
Length-姓名长度错误,姓名长度2-10!

From the above output, we can see that the application system has verified the incoming data and returned the corresponding data verification result.

2.2 URL parameter verification

Generally, GET requests pass parameters in the URL. In this case, you can directly specify the verification rules of the parameters through annotations. The following demonstrates through examples.

@Validated
public class UserController {
    
    
    @RequestMapping("/query")
    public String query(@Length(min = 2, max = 1, message ="姓名长度错误,姓名长度2-10!")
                        @RequestParam(name = "name", required = true) String name,
                        @Min(value = 1, message = "年龄最小只能1")
                        @Max(value = 99, message = "年龄最大只能9")
                        @RequestParam(name = "age", required = true) int age) {
    
    
        System.out.println(name + " , " + age);
        return name + " , " + age;
    }
}

In the above example, @Range, @Min, @Max and other annotations are used to verify the parameters passed in the URL. It should be noted that using the @Valid annotation is invalid, you need to add the @Validated annotation to the controller where the method is located to make the validation take effect.

2.3 JavaBean object cascade verification

For ordinary attribute fields in JavaBean objects, we can directly use annotations for data verification, so what if it is an associated object? In fact, it is also very simple. Adding the @Valid annotation to the attribute can be used as an internal attribute of the attribute object for verification (verify the User object, and the UserDetail field can be verified). The sample code is as follows:

public class User {
    
    
    @Size(min = 3, max = 5, message = "list的Size在[3,5]")
    private List<String> list;
    @NotNull
    @Valid
    private Demo3 demo3;
}

public class UserDetail {
    
    
    @Length(min = 5,max = 17,message = "length长度在[5,17]之间")
    private String extField;
}

In the above example, adding @Valid to the attribute can perform data validation on the fields of the associated object UserDetail in User.

2.4 Group verification

In different situations, the data verification rules for JavaBean objects may be different, and sometimes some attribute fields in JavaBean need to be verified separately according to the data status. At this time, the group verification function can be used, that is, a group of constraints is enabled according to the state. The annotation of Hibernate Validator provides the groups parameter, which is used to specify the group. If the groups parameter is not specified, it belongs to the javax.validation.groups.Default group by default.

The following example demonstrates group verification. First, create groups GroupA and GroupB, the sample code is as follows:

public interface GroupA {
    
        
}
public interface GroupB {
    
    
}

In the above example, we define two interfaces, GroupA and GroupB, as groups of two verification rules. Then, create the entity class Person and define the verification grouping rules in related fields. The sample code is as follows:

public class User {
    
    
    @NotBlank(message ="userId不能为空",groups = {
    
    GroupA.class})
/**用户id*/
    private Integer userId;
    @NotBlank(message ="用户名不能为空",groups = {
    
    GroupA.class})
    /**用户id*/
    private String name;

    @Length(min = 30,max = 40,message = "必须在[30,40]",groups = {
    
    GroupB.class})
    @Length(min = 20,max = 30,message = "必须在[20,30]",groups = {
    
    GroupA.class})
    /**用户名*/
    private int age;
}

In the above example, the userName field defines two group verification rules, GroupA and GroupB. The verification rule for GroupA is that the age is between 20 and 30, and the verification rule for GroupB is that the age is between 30 and 40. Finally, use the validation group:

@RequestMapping("/save")
public String save(@RequestBody @Validated({
    
    GroupA.class, Default.class}) Person person, BindingResult result) {
    
    
    System.out.println(JSON.toJSONString(result.getAllErrors()));
return "success";

In the above example, the {GroupA.class,Default.class} parameter is added to the @Validated annotation, indicating that the GroupA validation rules are used for the fields that define group validation, and the default rules are used for other fields.

3. Custom verification

Hibernate Validator supports custom validation rules. By customizing the validation rules, some complex and special data validation functions can be realized. The following example demonstrates how to create and use custom validation rules.

3.1 Declare a custom validation annotation

First, define a new validation annotation @CustomAgeValidator, the sample code is as follows:

    @Min(value = 18, message ="年龄最小不能小于18")
    @Max(value = 120, message ="年龄最大不能超过120")
    @Constraint(validatedBy = {
    
    }) //不指定校验器
    @Documented
    @Target({
    
    ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CustomAgeValidator {
    
    
        String message() default "年龄大小必须大于18并且小于123";
        Class<?>[] groups() default {
    
    };
        Class<? extends Payload>[] payload() default {
    
    };
    }

In the above example, we created the CustomAgeValidator custom annotation for customizing age data validation rules.

3.2 Using custom validation annotations

After creating the custom validation annotation CustomAgeValidator, use the custom combined annotation on the age attribute of User. The sample code is as follows:

@public class User {
    
    
    @NotBlank(message ="姓名不允许为空!")
    @Length(min = 2,max = 10,message ="姓名长度错误,姓名长度2-10!")
    private String name;
    @CustomAgeValidator
    private int age;
    @NotBlank(message ="地址不能为空!")
    private String address;
    @Pattern(regexp = "((13[-9])|(14[5,7,9])|(15([-3]][5-9]))|(166)(17[.1,3,5,6,7,8])l(18[0-9])I(19[8|9]))\\d{8}$", message ="手机号格式错误")
    private String phone;
    @Email(message ="邮箱格式错误")
    private String email;
    //省略get和set
}

In the above example, we add the @CustomAgeValidator custom annotation to the age field that requires special validation, so that the age field will use our custom validation rules.

Guess you like

Origin blog.csdn.net/weixin_45627039/article/details/131888166