用于检查几个整数值之一的 Bean 验证

Bas*_*que 1 java integer bean-validation

使用Jakarta Bean Validation版本 2 或 3,如何检查某个intInteger成员字段是否具有一组有限值中的一个?

\n

对于一个人为的过度简化的示例,请考虑此记录代表一个桶,其容量字段应容纳 50 或 55。

\n
record Barrel ( \n    UUID id , \n    int capacity   // Constrain to a value of either 50 or 55. \n) {}\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x9e\xa5 我将如何注释该capacity字段以确保它仅具有5055作为其数值?

\n

如果该capacity字段的类型为String,我可以@Pattern与正则表达式一起使用。

\n
public record Barrel(\n    @NotNull \n    UUID id , \n    @NotNull \n    @Pattern ( regexp = "50|55" )  // Constrain to a value of either "50" or "55". \n    String capacity\n) {}\n
Run Code Online (Sandbox Code Playgroud)\n

运行它。

\n
package work.basil.example.beanval;\n\nimport jakarta.validation.ConstraintViolation;\nimport jakarta.validation.Validation;\nimport jakarta.validation.Validator;\nimport jakarta.validation.ValidatorFactory;\n\nimport java.util.Set;\nimport java.util.UUID;\n\npublic class App\n{\n    public static void main ( String[] args )\n    {\n        App app = new App();\n        app.demo();\n    }\n\n    private void demo ( )\n    {\n        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();\n        Validator validator = factory.getValidator();\n\n        Barrel barrel = new Barrel( UUID.fromString( "e78456ac-6f12-45ae-b8e1-c3b8193a920e" ) , "55" );\n        Set < ConstraintViolation < Barrel > > violations = validator.validate( barrel );\n        System.out.format( "INFO - Found %d violations.\\n" , violations.size() );\n        violations.forEach( barrelConstraintViolation -> System.out.println( barrelConstraintViolation.getMessage() ) );\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x9e\xa5 如何使int/获得Integer与 a相同的效果String

\n

Nik*_*los 5

我认为没有内置的验证器。不过,构建自己的系统很简单:

  1. 添加约束注释:

     import static java.lang.annotation.ElementType.FIELD;
     import static java.lang.annotation.ElementType.PARAMETER;
     import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
     import javax.validation.Constraint;
     import javax.validation.Payload;
     import java.lang.annotation.Retention;
     import java.lang.annotation.Target;
    
     @Target({FIELD,PARAMETER})
     @Retention(RUNTIME)
     @Constraint(validatedBy = OneOfValidator.class)
     public @interface OneOf {
    
         String message() default "...provide your default message here...";
    
         Class<?>[] groups() default { };
    
         Class<? extends Payload>[] payload() default { };
    
         /** The array of allowed values. */
         int[] value();
     }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,它引用实际的验证器类(见下文),并且您必须提供适当的验证消息。

  2. 创建验证器逻辑:

     import static java.util.stream.Collectors.toSet;
    
     import javax.validation.ConstraintValidator;
     import javax.validation.ConstraintValidatorContext;
     import java.util.Arrays;
     import java.util.Set;
    
     public class OneOfValidator implements ConstraintValidator<OneOf, Integer> {
    
         private Set<Integer> allowedValues;
    
         @Override
         public void initialize(OneOf constraintAnnotation) {
             allowedValues = Arrays.stream(constraintAnnotation.value()).boxed().collect(toSet());
         }
    
         @Override
         public boolean isValid(Integer i, ConstraintValidatorContext constraintValidatorContext) {
             return i == null || allowedValues.contains(i);
         }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用:

     @OneOf({50,55})
     int capacity;
    
    Run Code Online (Sandbox Code Playgroud)

注意:对于像您这样的用例,是否enum更合适?