在本教程中,我们将学习如何使用 Hibernate 验证器验证 Spring 启动 REST API DTO 请求。
在Java中,Java Bean Validation框架已经成为处理Java项目中验证的事实标准。
JSR 380 是用于 Bean 验证的 Java API 规范,它使用 @NotNull、@Min 和 @Max 等注释确保 Bean 的属性满足特定条件。
Hibernate验证器是验证API的参考实现。
我们创建并使用DTO(数据传输对象)在客户端和服务器之间转换数据。
数据传输对象设计模式是一种常用的设计模式。它基本上用于一次性将具有多个属性的数据从客户端传递到服务器,以避免多次调用远程服务器。
我们不会将 Java Bean 验证注释添加到 JPA 实体,而是将 Java Bean 验证注释添加到 DTO,因为我们将在 REST API 的请求和响应中使用 DTO。
重要的 Java Bean 验证
- @NotNull验证批注的属性值是否不为 null。
- @Size验证批注属性值的大小是否介于属性 min 和 max 之间;可以应用于字符串、集合、映射和数组属性。
- @Min验证批注属性的值不小于 value 属性。
- @Max验证批注属性的值不大于 value 属性。
- @Email验证批注属性是否为有效的电子邮件地址。
- @NotEmpty验证属性是否为空或空;可以应用于字符串、集合、映射或数组值。
- @NotBlank只能应用于文本值,并验证属性是否为 null 或空格。
在此处查看完整列表Source Code Examples
Spring 引导中的验证
Spring boot 提供了与 Hibernate 验证器的良好集成支持。
我们将使用 Hibernate Validator,它是 Bean 验证 API 的参考实现之一。
从 Boot 2.3 开始,我们需要显式添加spring-boot-starter-validation依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
弹簧引导 DTO 验证示例
1. 在 STS 中创建 Spring 引导应用程序
=> 在 Spring 工具套件中创建 Spring 引导项目 [STS]
- 春网
- 验证
- 春季数据 JPA
- H2 数据库
2. Maven 依赖项
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>net.javaguides</groupId>
<artifactId>springboot-validation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-validation</name>
<description>Demo project for Spring Boot and Hibernate Validator</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. 创建用户类
package net.javaguides.springboot.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "users")
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name", nullable = false)
private String name;
private String email;
private String password;
public User() {
}
public User(String name, String email, String password) {
super();
this.name = name;
this.email = email;
this.password = password;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4. 创建用户Dto 类
package net.javaguides.springboot.dto;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
public class UserDto {
private long id;
// user name should not be null or empty
// user name should have at least 2 characters
@NotEmpty
@Size(min = 2, message = "user name should have at least 2 characters")
private String name;
// email should be a valid email format
// email should not be null or empty
@NotEmpty
@Email
private String email;
// password should not be null or empty
// password should have at least 8 characters
@NotEmpty
@Size(min = 8, message = "password should have at least 8 characters")
private String password;
public UserDto() {
}
public UserDto(String name, String email, String password) {
super();
this.name = name;
this.email = email;
this.password = password;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
请注意,我们在下面添加了 Java Bean 验证注释到UserDto类:
- @NotEmpty验证属性是否为空或空;可以应用于字符串、集合、映射或数组值。
- @Size验证批注属性值的大小是否介于属性 min 和 max 之间;可以应用于字符串、集合、映射和数组属性。
- @Email验证批注属性是否为有效的电子邮件地址。
5. 配置数据库
6. 创建用户存储库
package net.javaguides.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import net.javaguides.springboot.model.User;
public interface UserRepository extends JpaRepository<User, Long>{
}
7. 创建用户服务类
package net.javaguides.springboot.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import net.javaguides.springboot.model.User;
import net.javaguides.springboot.repository.UserRepository;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User createUser(User user) {
return userRepository.save(user);
}
}
8. 创建用户控制器类
package net.javaguides.springboot.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.javaguides.springboot.model.User;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.service.UserService;
@RestController
@RequestMapping("/api/")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("users")
public ResponseEntity<UserDto> createUser(@Valid @RequestBody UserDto userDto){
// convert UserDto to User entity
User user = new User();
user.setName(userDto.getName());
user.setEmail(userDto.getEmail());
user.setPassword(userDto.getPassword());
User savedUser = userService.createUser(user);
// convert User entity to UserDto class
UserDto userResponse = new UserDto();
userResponse.setId(savedUser.getId());
userResponse.setName(savedUser.getName());
userResponse.setEmail(savedUser.getEmail());
// don't provide password to client
// userResponse.setPassword(savedUser.getPassword());
return new ResponseEntity<User>(userResponse, HttpStatus.CREATED);
}
}
9. 创建验证处理程序
package net.javaguides.springboot.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class ValidationHandler extends ResponseEntityExceptionHandler{
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) ->{
String fieldName = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(fieldName, message);
});
return new ResponseEntity<Object>(errors, HttpStatus.BAD_REQUEST);
}
}
10.运行弹簧启动应用程序
package net.javaguides.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootValidationApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootValidationApplication.class, args);
}
}
11. 使用邮递员客户端进行测试
11. 结论
在本教程中,我们学习了如何使用Hibernate验证器在Spring boot REST API中验证DTO对象。
本教程的源代码可在我的 GitHub 存储库中找到,网址为GitHub - RameshMF/springboot-validation: Validation in Spring Boot REST API with Hibernate Validator (Java Bean Validation Annotations)
从 Boot 2.3 开始,我们需要显式添加spring-boot-starter-validation依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>