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
<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.16.Final</version></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 配置
@Beanpublic javax.validation.Validator localValidatorFactoryBean() {return new LocalValidatorFactoryBean();}
XML 配置
<bean id="validator"class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
1.3. 添加 bean 验证注解
在模型类中添加 Bean 验证注解,该注解将存储请求正文数据,例如@NotEmpty和@Email。
Java 配置
import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.validation.constraints.Email;import javax.validation.constraints.NotEmpty;@Entity@Table(name = "tbl_employee")public class Employee implements Serializable{private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@NotEmpty(message = "First name must not be empty")private String firstName;@NotEmpty(message = "Last name must not be empty")private String lastName;@NotEmpty(message = "Email must not be empty")@Email(message = "Email must be a valid email address")private String email;public Employee() {}//setters and getters@Overridepublic String toString() {return "EmployeeVO [id=" + id + ", firstName=" + firstName + ",lastName=" + lastName + ", email=" + email + "]";}}
1.4. 处理ConstraintViolationException
如果发生任何验证失败,Spring 将抛出ConstraintViolationException。 我们可以使用@ExceptionHandler处理任何返回有意义的 JSON 错误响应的事件。
CustomExceptionHandler.java
@ControllerAdvice@ResponseBodypublic class CustomExceptionHandler extends ResponseEntityExceptionHandler{@ExceptionHandler(ConstraintViolationException.class)public final ResponseEntity<ErrorResponse> handleConstraintViolation(ConstraintViolationException ex,WebRequest request){List<String> details = ex.getConstraintViolations().parallelStream().map(e -> e.getMessage()).collect(Collectors.toList());ErrorResponse error = new ErrorResponse(BAD_REQUEST, details);return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);}}
2. 查询和路径参数验证
在 Spring REST 中,通过@PathVariable捕获请求 URI 中的参数,并通过@RequestParam捕获所有查询参数。
请注意,必须添加 maven 依赖项,并且应按上述说明处理ConstraintViolationException。
2.1. 启用验证
查询和路径参数验证并不简单。 我们需要显式创建 bean MethodValidationPostProcessor,它将处理@Validated注解。
XML 配置
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
Java 配置
@Beanpublic MethodValidationPostProcessor methodValidationPostProcessor() {return new MethodValidationPostProcessor();}
2.2. 向参数添加验证
- 使用如上所述的 JSR-303 注解。
- 在控制器顶部使用
@Validated注解,因此适用于其中的所有方法。
@RestController@RequestMapping(value = "/employee-management",produces = { MediaType.APPLICATION_JSON_VALUE })@Validatedpublic class EmployeeRESTController{@GetMapping("/employees/{id}")Employee getEmployeeById(@PathVariable@Min(value = 1, message = "id must be greater than or equal to 1")@Max(value = 1000, message = "id must be lower than or equal to 1000") Long id){return repository.findById(id).orElseThrow(() -> new RecordNotFoundException("Employee id '" + id + "' does no exist"));}}
3. 演示
3.1. 请求正文验证
API 请求 1
HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/Headers:AUTH_API_KEY: abcd123456Content-Type: application/jsonBody:{"firstName": "","lastName": "Gupta","email": "abc@gmail.com"}
API 响应 1
{"message":"BAD_REQUEST","details":["First name must not be empty"]}
API 请求 2
HTTP POST : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/Headers:AUTH_API_KEY: abcd123456Content-Type: application/jsonBody:{"firstName": "","email": "abc@gmail.com"}
API 响应 2
{"message":"BAD_REQUEST","details":["First name must not be empty","Last name must not be empty"]}
3.2. 路径参数验证
API 请求 1
HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/0Headers:AUTH_API_KEY: abcd123456Content-Type: application/json
API 响应 1
{"message":"BAD_REQUEST","details":["id must be greater than or equal to 1"]}
API 请求 2
HTTP GET : http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/5000Headers:AUTH_API_KEY: abcd123456Content-Type: application/json
API 请求 2
{“message”:”BAD_REQUEST”,“details”:[“id must be lower than or equal to 1000”]}
学习愉快!
