在本教程中,我们将学习如何使用 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。
在此处查看完整列表Source Code Examples
Spring boot 提供了与 Hibernate 验证器的良好集成支持。
我们将使用 Hibernate Validator,它是 Bean 验证 API 的参考实现之一。
从 Boot 2.3 开始,我们需要显式添加spring-boot-starter-validation依赖项:
-
org.springframework.boot -
spring-boot-starter-validation
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-
4.0.0 -
-
org.springframework.boot -
spring-boot-starter-parent -
2.4.3 -
-
-
net.javaguides -
springboot-validation -
0.0.1-SNAPSHOT -
springboot-validation -
Demo project for Spring Boot and Hibernate Validator -
-
1.8 -
-
-
-
org.springframework.boot -
spring-boot-starter-data-jpa -
-
-
org.springframework.boot -
spring-boot-starter-validation -
-
-
org.springframework.boot -
spring-boot-starter-web -
-
-
-
com.h2database -
h2 -
runtime -
-
-
org.springframework.boot -
spring-boot-starter-test -
test -
-
-
-
-
-
-
org.springframework.boot -
spring-boot-maven-plugin -
-
-
-
3. 创建用户类
让我们创建一个新的模型包。在此模型包中,创建一个用户JPA 类并向其中添加以下内容:
- 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 类
让我们创建一个dto包。在dto包中,创建UserDto类并向其中添加以下内容:
- 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验证批注属性是否为有效的电子邮件地址。
6. 创建用户存储库
让我们创建一个存储库包。在此包中,创建一个与数据库通信的UserRepository类。添加以下内容:
- package net.javaguides.springboot.repository;
-
- import org.springframework.data.jpa.repository.JpaRepository;
-
- import net.javaguides.springboot.model.User;
-
- public interface UserRepository extends JpaRepository
{ -
- }
7. 创建用户服务类
让我们创建一个服务包。在此包中,创建一个UserService类并向其中添加以下代码:
- 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. 创建用户控制器类
让我们创建一个控制器包。在此包中,创建一个UserController类并向其添加以下内容:
- 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
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
(userResponse, HttpStatus.CREATED); - }
- }
请注意,我们通过在createUser() 方法中添加@Valid注释来启用 Spring Rest 控制器上的验证@RequestBody。
9. 创建验证处理程序
让我们创建一个验证处理程序来自定义验证响应。
要自定义响应验证,我们需要扩展ResponseEntityExceptionHandler类并覆盖handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request)方法。
让我们创建ValidationHandler类并向其添加以下内容:
- 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
- HttpHeaders headers, HttpStatus status, WebRequest request) {
-
- Map
errors = new HashMap<>(); - ex.getBindingResult().getAllErrors().forEach((error) ->{
-
- String fieldName = ((FieldError) error).getField();
- String message = error.getDefaultMessage();
- errors.put(fieldName, message);
- });
- return new ResponseEntity
- }
- }
10.运行弹簧启动应用程序
使用主类运行 Spring 引导应用程序:
- 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. 使用邮递员客户端进行测试
下面的屏幕截图显示了使用Hibernate验证器对Spring boot REST API的验证:
在本教程中,我们学习了如何使用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依赖项:
org.springframework.boot
spring-boot-starter-validation