SpringBoot actual combat (15) | one of server-side parameter verification

  java, springboot, validate

Preface

It is estimated that many friends think that parameter verification is the responsibility of the client, not the server. In fact, this is wrong. Anyone who has studied Web security knows that client authentication is only the first hurdle. Its parameter verification is not safe. Once it is caught by the intentional person, he can have various methods to simulate the Http request of the system and access the key data of the database. If it is light, it will lead to server downtime; if it is heavy, it will reveal the data. Therefore, it is necessary to set up a second checkpoint at this time, and the server has verified it.

Server-side Verification of Old Projects

@RestController
@RequestMapping("/student")
public class ValidateOneController {

    @GetMapping("/id")
    public Student findStudentById(Integer id){
        if(id == null){
              logger.error("id 不能为空!");
              throw new NullPointerException("id 不能为空");
        }
        return studentService.findStudentById(id);
    }
}

Looking at the above code, checking one by one is so troublesome. Do we have a good unified verification method? Since SpringBoot is omnipotent. The answer is certainly yes.

Among them, Bean Validator and Hibernate Validator are two sets of frameworks for verification. Both follow JSR-303 and can be mixed. In view of the differences in some Validator annotations between the two, for example @Length does not exist in Bean Validator, so I choose to mix them here.

JSR-303

JSR-303 is a sub-specification in JAVA EE 6, called Bean Validation. Hibernate Validator is the reference implementation of Bean Validation. Hibernate Validator provides the implementation of all built-in constraints in JSR 303 specification, in addition to some additional constraints. These Constraint are all implemented by annotations. Please look at the following two tables.

Constraints built into Bean Validation:

annotation Effect
@Null Annotated parameter must be empty
@NotNull Annotated parameter cannot be empty
@AssertTrue Argument to be annotated must be True
@AssertFalse Argument to be annotated must be False
@Min(value) The annotated parameter must be a number and its value must be greater than or equal to value
@Max(value) The annotated parameter must be a number and its value must be less than or equal to value
@DecimaMin(value) The annotated parameter must be a number and its value must be greater than or equal to value
@DecimaMax(value) The annotated parameter must be a number and its value must be less than or equal to value
@Size(max, min) The annotated parameter size must be within the specified range
@Past The annotated parameter must be a past date
@Future The annotated parameter must be a future date
@Pattern(value) The annotated parameter must conform to the specified regular expression
@Digits(integer, fraction) The annotated parameter must be a number and its value must be within the acceptable range
@NotBlank The value of the annotated parameter is not null (not null, length is 0 after removing the first space), which is different from @NotEmpty. @NotBlank is only applied to strings and the spaces in strings will be removed during comparison.

Hibernate Validator additional constraints:

annotation Effect
@NotEmpty The value of the annotated parameter is not null and empty (string length is not 0, collection size is not 0)
@Email The annotated parameter must be an e-mail address
@Length The annotated string length must be within the specified range
@Range The annotated parameter must be within the specified range

Preparatory work

  • SpringBoot 2.1.3
  • IDEA
  • JDK8

Pom file dependency

<!-- web 启动类 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- test 单元测试类 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<!-- lombok 依赖用于简化 bean -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

Entity class

For testing, parameter verification rules are added.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private Integer id;

    @NotBlank(message = "学生名字不能为空")
    @Length(min = 2, max = 10, message = "name 长度必须在 {min} - {max} 之间")
    private String name;

    @NotNull(message = "年龄不允许为空")
    @Min(value = 0, message = "年龄不能低于 {value} 岁")
    private Integer age;
}

Controller layer

Two methods were written, one for checking common parameters and the other for checking objects.

@Validated //开启数据校验,添加在类上用于校验方法,添加在方法参数中用于校验参数对象。(添加在方法上无效)
@RestController
@RequestMapping("/student")
public class ValidateOneController {

    /**
     * 普通参数校验
     * @param name
     * @return
     */
    @GetMapping("/name")
    public String findStudentByName(@NotBlank(message = "学生名字不能为空")
    @Length(min = 2, max = 10, message = "name 长度必须在 {min} - {max} 之间")String name){
        return "success";
    }

    /**
     * 对象校验
     * @param student
     * @return
     */
    @PostMapping("/add")
    public String addStudent(@Validated @RequestBody Student student){
        return "success";
    }
}

Postman test

Verify the test results of common parameters:

As can be seen in the figure below, I am not inhttp://localhost: 8080/student/name address, add name parameter, and send it to the background to check out the exception immediately. This anomaly information is the verification anomaly information defined by me.

校验普通参数测试结果

Test result of verification object:

校验对象测试截图

The result is a bit long:

As can be seen in the figure below, I visitedhttp://localhost: 8080/student/add passed a parameter object, but the object cannot pass the verification rule. For example, the age parameter is negative and the length of the name parameter is too large. When passed to the background, the exception will be verified immediately. This anomaly information is the verification anomaly information defined by me.

校验对象测试结果

Complete code

https://github.com/turoDog/De …

If you think it is helpful to you, please give a Star before you leave. thank you very much.

Postscript

If this article is of any help to you, please help me look good. Your good looks are my motivation to persist in writing.

In addition, after the attention is sent1024Free study materials are available.

For details, please refer to this old article:Python, C++, Java, Linux, Go, Front End, Algorithm Data Sharing

一个优秀的废人