Spring Boot Validation

SpringBoot 参数校验

校验框架

Bean 校验框架的事实标准:Hibernate Validator

依赖

从 SpringBoot 2.3 开始,需要显式地引入 spring-boot-starter-validation 依赖

领域模型

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users") // user 是数据库的保留字
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;
}

使用 @NotBlank 注解表示 name 和 email 的值不能为空。

数据访问层:

public interface UserRepository extends JpaRepository<User, Long> {}

控制器层

@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public User addUser(@Valid @RequestBody User user) {
return userService.addUser(user);
}
}

当 SpringBoot 发现一个带有 @Valid 注解的参数,它会自动装配 Hibernate Validation 并校验该参数。
在校验失败时,抛出 MethodArgumentNotValidException 异常。

全局异常处理

/**
* 全局校验异常处理
* */
@ControllerAdvice
public class ValidExceptionHandler {
/**
* 以 JSON 格式返回校验异常信息
* */
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public Map<String, String> handleValidationException(MethodArgumentNotValidException e) {
Map<String, String> errors = new HashMap<>();
e.getBindingResult()
.getAllErrors()
.forEach(error -> {
String fieldName = ((FieldError)error).getField(); // 字段名
String errorMessage = error.getDefaultMessage(); // 校验失败信息
errors.put(fieldName, errorMessage);
});
return errors;
}
}

测试

@WebMvcTest
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
private ObjectMapper objectMapper = new ObjectMapper();
/**
* 参数校验成功测试
* */
@Test
public void whenPostRequestToUserAndValidUser_thenCorrectResponse() throws Exception {
User user = User.builder()
.name("Alex")
.email("alex@gamil.com")
.build();
String json = objectMapper.writeValueAsString(user);
mockMvc.perform(post("/user")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
/**
* 参数校验失败测试
* */
@Test
public void whenPostRequestToUserAndInvalidUser_thenCorrectResponse() throws Exception {
User userWithoutName = User.builder()
.email("alex@gmail.com")
.build();
String json = objectMapper.writeValueAsString(userWithoutName);
mockMvc.perform(post("/user")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.name", Is.is("Name is mandatory")));
}
}

校验注解

注解 适用类型 说明
@Null 任何类型
@NotNull 任何类型
@NotEmpty 字符串、集合、Map 元素不能为 null 且不能为空
@NotBlank 字符串 字符串不能为 null 并且不能只包含空白字符
@Size(min=, max=) 字符串、集合、Map 容器大小,包含边界
@Max(value=) 数值 最大值
@Min(value=) 数值 最小值
@Digits(integer=, fraction=) 数值或字符串 数位
@Negative 数值 负数,不能是零
@NegativeOrZero 数值 负数或零
@Positive 数值 正数,不能是零
@PositiveOrZero 数值 正数或零
@Pattern(regex=, flags=) 字符串 字符串符合正则表达式
@Email 字符串
@DecimalMax(value=, inclusive=) 数值或字符串 最大值
@DecimalMin(value=, inclusive=) 数值或字符串 最小值
@Future 日期类型 将来日期
@FutureOrPresent 日期类型 现在或将来日期
@Past 日期类型 过去日期
@PastOrPresent 日期类型 过去或现在日期
@AssertFalse 布尔值
@AssertTrue 布尔值

数值包括:BigDecimal, BigInteger, byte, short, int, long

参阅

posted @   廖子博  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示