Spring Boot中如何验证DTO的字符串变量仅包含指定枚举值
验证RequestDto中String类型status字段的方案
方案一:使用Jakarta Validation的@Pattern注解
适合简单场景,直接通过正则匹配允许的字符串值:
import jakarta.validation.constraints.Pattern; import lombok.Data; @Data class RequestDto { // 严格匹配"new"或"retry",大小写敏感 @Pattern(regexp = "^(new|retry)$", message = "status只能是new或retry") private String status; }
方案二:自定义Validation注解
适合枚举值可能变动的场景,从枚举中动态获取允许的字符串集合,避免硬编码:
1. 定义自定义校验注解
import jakarta.validation.Constraint; import jakarta.validation.Payload; import java.lang.annotation.*; @Documented @Constraint(validatedBy = StatusValidator.class) @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidStatus { String message() default "status只能是new或retry"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2. 实现校验逻辑
import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; public class StatusValidator implements ConstraintValidator<ValidStatus, String> { private Set<String> allowedStatuses; @Override public void initialize(ValidStatus constraintAnnotation) { // 从枚举中提取所有合法的字符串值 allowedStatuses = Arrays.stream(Status.values()) .map(Status::getStatus) .collect(Collectors.toSet()); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 若允许status为null,可添加`value == null ||`判断,按需调整 return value != null && allowedStatuses.contains(value); } }
3. 在DTO中使用注解
@Data class RequestDto { @ValidStatus private String status; }
方案三:通过枚举转换验证
在DTO的setter方法中尝试将字符串转为枚举,转换失败则抛出异常:
import lombok.Data; import java.util.Arrays; @Data class RequestDto { private String status; public void setStatus(String status) { // 尝试匹配枚举,不匹配则抛出异常 Status.fromString(status); this.status = status; } } // 给Status枚举添加静态匹配方法 @Data public enum Status { NEW("new"), RETRY("retry"); private final String status; Status(String status) { this.status = status; } public static Status fromString(String status) { return Arrays.stream(values()) .filter(s -> s.status.equals(status)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("status只能是new或retry")); } }
内容的提问来源于stack exchange,提问作者Vishnupriya
相关产品推荐
相关产品推荐

