https://howtodoinjava.com/spring-restful/request-body-parameter-validation/

学习验证请求正文(发布到 Spring REST API 的 JSON)。 还使用 Hibernate 验证器 2.x 验证资源 URI 中的@PathVariable@RequestParam参数。

在此 SpringRest 验证示例中,我们将在为 CRUD 示例创建的 REST API 中添加验证。

1. 使用 Hibernate 验证器的请求正文验证

1.1. Maven 依赖

pom.xml

  1. <dependency>
  2. <groupId>org.hibernate.validator</groupId>
  3. <artifactId>hibernate-validator</artifactId>
  4. <version>6.0.16.Final</version>
  5. </dependency>

这可传递地将对 Bean 验证 API 的依赖关系拉到javax.validation:validation-api: 2.0.1.Final

1.2. 启用 bean 验证

SpringBoot 中,如果类路径上有任何 JSR-303 实现(例如Hibernate 验证器 2.0 ),则将自动启用 Bean 验证。

如果不使用 Spring Boot,则需要添加LocalValidatorFactoryBean

Java 配置

  1. @Bean
  2. public javax.validation.Validator localValidatorFactoryBean() {
  3. return new LocalValidatorFactoryBean();
  4. }

XML 配置

  1. <bean id="validator"
  2. class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

1.3. 添加 bean 验证注解

在模型类中添加 Bean 验证注解,该注解将存储请求正文数据,例如@NotEmpty@Email

Java 配置

  1. import java.io.Serializable;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.Table;
  7. import javax.validation.constraints.Email;
  8. import javax.validation.constraints.NotEmpty;
  9. @Entity
  10. @Table(name = "tbl_employee")
  11. public class Employee implements Serializable
  12. {
  13. private static final long serialVersionUID = 1L;
  14. @Id
  15. @GeneratedValue(strategy = GenerationType.IDENTITY)
  16. private Long id;
  17. @NotEmpty(message = "First name must not be empty")
  18. private String firstName;
  19. @NotEmpty(message = "Last name must not be empty")
  20. private String lastName;
  21. @NotEmpty(message = "Email must not be empty")
  22. @Email(message = "Email must be a valid email address")
  23. private String email;
  24. public Employee() {
  25. }
  26. //setters and getters
  27. @Override
  28. public String toString() {
  29. return "EmployeeVO [id=" + id + ", firstName=" + firstName + ",
  30. lastName=" + lastName + ", email=" + email + "]";
  31. }
  32. }

1.4. 处理ConstraintViolationException

如果发生任何验证失败,Spring 将抛出ConstraintViolationException。 我们可以使用@ExceptionHandler处理任何返回有意义的 JSON 错误响应的事件。

CustomExceptionHandler.java

  1. @ControllerAdvice
  2. @ResponseBody
  3. public class CustomExceptionHandler extends ResponseEntityExceptionHandler
  4. {
  5. @ExceptionHandler(ConstraintViolationException.class)
  6. public final ResponseEntity<ErrorResponse> handleConstraintViolation(
  7. ConstraintViolationException ex,
  8. WebRequest request)
  9. {
  10. List<String> details = ex.getConstraintViolations()
  11. .parallelStream()
  12. .map(e -> e.getMessage())
  13. .collect(Collectors.toList());
  14. ErrorResponse error = new ErrorResponse(BAD_REQUEST, details);
  15. return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
  16. }
  17. }

2. 查询和路径参数验证

在 Spring REST 中,通过@PathVariable捕获请求 URI 中的参数,并通过@RequestParam捕获所有查询参数。

请注意,必须添加 maven 依赖项,并且应按上述说明处理ConstraintViolationException

2.1. 启用验证

查询和路径参数验证并不简单。 我们需要显式创建 bean MethodValidationPostProcessor,它将处理@Validated注解。

XML 配置

  1. <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

Java 配置

  1. @Bean
  2. public MethodValidationPostProcessor methodValidationPostProcessor() {
  3. return new MethodValidationPostProcessor();
  4. }

2.2. 向参数添加验证

  • 使用如上所述的 JSR-303 注解。
  • 在控制器顶部使用@Validated注解,因此适用于其中的所有方法。
  1. @RestController
  2. @RequestMapping(value = "/employee-management",
  3. produces = { MediaType.APPLICATION_JSON_VALUE })
  4. @Validated
  5. public class EmployeeRESTController
  6. {
  7. @GetMapping("/employees/{id}")
  8. Employee getEmployeeById(@PathVariable
  9. @Min(value = 1, message = "id must be greater than or equal to 1")
  10. @Max(value = 1000, message = "id must be lower than or equal to 1000") Long id)
  11. {
  12. return repository.findById(id)
  13. .orElseThrow(() -> new RecordNotFoundException("Employee id '" + id + "' does no exist"));
  14. }
  15. }

3. 演示

3.1. 请求正文验证

API 请求 1

  1. HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/
  2. Headers:
  3. AUTH_API_KEY: abcd123456
  4. Content-Type: application/json
  5. Body:
  6. {
  7. "firstName": "",
  8. "lastName": "Gupta",
  9. "email": "abc@gmail.com"
  10. }

API 响应 1

  1. {
  2. "message":"BAD_REQUEST",
  3. "details":["First name must not be empty"]
  4. }

API 请求 2

  1. HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/
  2. Headers:
  3. AUTH_API_KEY: abcd123456
  4. Content-Type: application/json
  5. Body:
  6. {
  7. "firstName": "",
  8. "email": "abc@gmail.com"
  9. }

API 响应 2

  1. {
  2. "message":"BAD_REQUEST",
  3. "details":
  4. [
  5. "First name must not be empty",
  6. "Last name must not be empty"
  7. ]
  8. }

3.2. 路径参数验证

API 请求 1

  1. HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/0
  2. Headers:
  3. AUTH_API_KEY: abcd123456
  4. Content-Type: application/json

API 响应 1

  1. {
  2. "message":"BAD_REQUEST",
  3. "details":["id must be greater than or equal to 1"]
  4. }

API 请求 2

  1. HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/5000
  2. Headers:
  3. AUTH_API_KEY: abcd123456
  4. Content-Type: application/json

API 请求 2

  1. {
  2. message”:”BAD_REQUEST”,
  3. details”:[“id must be lower than or equal to 1000”]
  4. }

下载源码

学习愉快!