SpringBoot中利用Bean Validation限制Test类Status字段禁用值
SpringBoot中Model类字段禁止特定取值的实现方案
问题背景
现有如下实体类:
public class Test { private String id; private String status; private Integer alertsCount; }
在SpringBoot的POST接口中,传入的JSON数据示例如下:
{ "id": "1", "status": "Cancelled", "alertCount": 10 }
需求:限制status字段不能取"Successfull"、"Cancelled"、"In Progress"、"On Hold"这些值。
实现方案
方案一:自定义校验注解(推荐,复用性高)
这种方式适合需要在多个地方复用该校验规则的场景。
1. 定义校验注解
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Documented @Constraint(validatedBy = ForbiddenStatusValidator.class) @Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface ForbiddenStatus { // 校验失败时的提示信息 String message() default "status字段不能使用指定的禁止值"; // 分组校验相关,默认空即可 Class<?>[] groups() default {}; // 负载信息,默认空即可 Class<? extends Payload>[] payload() default {}; // 可配置的禁止取值,默认设置题目要求的几个值 String[] value() default {"Successfull", "Cancelled", "In Progress", "On Hold"}; }
2. 实现校验逻辑
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; public class ForbiddenStatusValidator implements ConstraintValidator<ForbiddenStatus, String> { private Set<String> forbiddenValues; @Override public void initialize(ForbiddenStatus constraintAnnotation) { // 初始化禁止取值集合 forbiddenValues = Arrays.stream(constraintAnnotation.value()) .collect(Collectors.toSet()); } @Override public boolean isValid(String status, ConstraintValidatorContext context) { // 允许status为null的情况,若不允许可改为 return !forbiddenValues.contains(status); return status == null || !forbiddenValues.contains(status); } }
3. 在实体类中应用注解
public class Test { private String id; // 应用自定义校验注解,可自定义提示信息 @ForbiddenStatus(message = "status不能为Successfull、Cancelled、In Progress、On Hold中的任意值") private String status; private Integer alertsCount; // 必须添加getter、setter方法,SpringBoot需要通过这些方法绑定请求参数 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public Integer getAlertsCount() { return alertsCount; } public void setAlertsCount(Integer alertsCount) { this.alertsCount = alertsCount; } }
4. 在接口中触发校验
在Controller的POST接口参数上添加@Valid或@Validated注解,开启参数校验:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @RestController public class TestController { @PostMapping("/test") public String submitTest(@Valid @RequestBody Test test) { // 执行业务逻辑 return "提交成功"; } }
方案二:使用@AssertTrue配合校验方法(快速实现,适合简单场景)
如果只是在当前实体类中使用该规则,可直接在类中添加校验方法:
import javax.validation.constraints.AssertTrue; import java.util.Set; public class Test { private String id; private String status; private Integer alertsCount; // 校验status是否合法,方法名需符合JavaBean规范(isXXX) @AssertTrue(message = "status不能为Successfull、Cancelled、In Progress、On Hold中的任意值") private boolean isStatusValid() { if (status == null) { return true; // 允许status为null,若不允许可返回false } return !Set.of("Successfull", "Cancelled", "In Progress", "On Hold").contains(status); } // getter、setter方法省略 }
同样需要在Controller接口参数上添加@Valid注解触发校验。
注意事项
- 确保项目引入了Spring Boot Validation依赖(Spring Boot 2.3及以上版本需手动引入):
<!-- Maven依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
- 若需要统一处理校验失败的异常,可添加全局异常处理器,返回标准化的错误响应。
内容的提问来源于stack exchange,提问作者rohan
相关产品推荐
相关产品推荐

