Spring Boot 中的数据校验

您所在的位置:网站首页 校验数据 Spring Boot 中的数据校验

Spring Boot 中的数据校验

2024-07-13 10:52| 来源: 网络整理| 查看: 265

1、概览

Spring Boot 通过 Hibernate Validator(Bean Validation 的实现)对数据验证提供了强大的支持。

本文将通过一个实际的 REST 应用带你了解如何在 Spring Boot 中校验数据。

2、Maven 依赖

在 pomx.ml 中添加 spring-boot-starter-web、spring-boot-starter-jpa 和 H2 database 依赖:

org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 2.1.214 runtime

从 Boot 2.3 开始,还需要明确添加 spring-boot-starter-validation 依赖:

org.springframework.boot spring-boot-starter-validation 3、示例 Domain 类

定义一个 JPA 实体类,User:

@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @NotBlank(message = "Name is mandatory") private String name; @NotBlank(message = "Email is mandatory") private String email; // 构造函数、Set、Set 方发省略 }

User 实体类很简单,它展示了如何使用 Bean Validation 的约束来限制 name 和 email 字段。

为简单起见,这里仅使用 @NotBlank 约束来约束目标字段。此外,还使用 message 属性指定了错误信息。

因此,当 Spring Boot 验证类实例时,受约束字段必须不为 null,且去除其两边空白后长度必须大于零。

除了 @NotBlank 之外,Bean Validation 还提供了许多其他方便的约束。可以对受约束的类应用和组合不同的验证规则。如需了解更多信息,请阅读官方的 Bean Validation 文档。

还要定义一个 UserRepository,用于把 User 保存到 H2 数据库:

@Repository public interface UserRepository extends CrudRepository {} 4、REST Controller

创建 UserController:

@RestController public class UserController { @PostMapping("/users") ResponseEntity addUser(@Valid @RequestBody User user) { // 存 储User return ResponseEntity.ok("User is valid"); }

当 Spring Boot 发现一个参数注解了 @Valid 时,它会自动启动默认的 JSR 380 实现 - Hibernate Validator,并验证该参数。

当目标参数未能通过验证时,Spring Boot 会抛出一个 MethodArgumentNotValidException 异常。

5、@ExceptionHandler 注解

Spring Boot 能自动验证传递给 addUser() 方法的 User 对象,这确实很方便,但这一过程中缺少的是如何处理验证结果?

@ExceptionHandler 注解允许我们通过一个方法处理指定类型的异常。

因此,可以用它来处理验证错误:

@ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) public Map handleValidationExceptions( MethodArgumentNotValidException ex) { Map errors = new HashMap(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return errors; }

如上,指定了 MethodArgumentNotValidException 异常作为要处理的异常。因此,当指定的 User 对象无效时,Spring Boot 将调用此方法。

该方法将每个无效字段的名称和验证后错误信息存储在 Map 中。然后,将 Map 以 JSON 表示形式发送回客户端,以便进一步处理。

6、测试 REST Controller

创建测试类,并注入 Mock UserRepository 接口实现、UserController 实例和 MockMvc 对象:

@RunWith(SpringRunner.class) @WebMvcTest @AutoConfigureMockMvc public class UserControllerIntegrationTest { @MockBean private UserRepository userRepository; @Autowired UserController userController; @Autowired private MockMvc mockMvc; //... }

由于只测试 Web 层,因此使用 @WebMvcTest 注解。它允许我们使用 MockMvcRequestBuilders 和 MockMvcResultMatchers 实现的静态方法集轻松测试请求和响应。

现在,在请求体中传递有效和无效的 User 对象来测试 addUser() 方法:

@Test public void whenPostRequestToUsersAndValidUser_thenCorrectResponse() throws Exception { MediaType textPlainUtf8 = new MediaType(MediaType.TEXT_PLAIN, Charset.forName("UTF-8")); String user = "{\"name\": \"bob\", \"email\" : \"[email protected]\"}"; mockMvc.perform(MockMvcRequestBuilders.post("/users") .content(user) .contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content() .contentType(textPlainUtf8)); } @Test public void whenPostRequestToUsersAndInValidUser_thenCorrectResponse() throws Exception { String user = "{\"name\": \"\", \"email\" : \"[email protected]\"}"; mockMvc.perform(MockMvcRequestBuilders.post("/users") .content(user) .contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(MockMvcResultMatchers.status().isBadRequest()) .andExpect(MockMvcResultMatchers.jsonPath("$.name", Is.is("Name is mandatory"))) .andExpect(MockMvcResultMatchers.content() .contentType(MediaType.APPLICATION_JSON_UTF8)); } }

也可以使用免费的 API 测试工具(如 Postman)来测试 REST Controller API。

7、运行示例应用

使用标准的 main() 方法运行示例项目:

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner run(UserRepository userRepository) throws Exception { return (String[] args) -> { User user1 = new User("Bob", "[email protected]"); User user2 = new User("Jenny", "[email protected]"); userRepository.save(user1); userRepository.save(user2); userRepository.findAll().forEach(System.out::println); }; } }

你可以在控制台中看到打印出来的几个 User 对象。

使用有效的 User 对象向 http://localhost:8080/users 端点发出 POST 请求,将返回字符串 “User is valid”。

使用不含 name 和 email 值的 User 对象进行 POST 请求,会返回以下响应:

{ "name":"Name is mandatory", "email":"Email is mandatory" } 8、总结

本文介绍了如何在 Spring Boot 中使用 @Valid 注解校验客户端提交的数据,以及如何处理校验失败的异常。

Ref:https://www.baeldung.com/spring-boot-bean-validation



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3