60071


みんなさん、お疲れ様です。  
今、spring freamworkで@Patternを利用して正規式を作ろうとしています。  
ですが、@Patternをjakarta-OROで表現したいです。何かオプションはありませんか？


CC BY-SA 4.0
2019-10-28T01:12:25.613
60029
2019-10-29T09:11:05.677
36374
question
spring
spring freamworkの@patternについて


[`Pattern`アノテーション](https://docs.oracle.com/javaee/7/api/javax/validation/constraints/Pattern.html)が受け付けるパターン文字列はJava方式の正規表現でなければならないというのが仕様([Bean
Validation](https://beanvalidation.org/specification/))上決まっているので、質問文通りのことは実現できません。

代わりに、独自の制約を定義します。具体的には、カスタムアノテーションと、それに対応するカスタムバリデータを作成します。

Springが利用しているBean Validation実装は[Hibernate
Validator](https://docs.spring.io/spring/docs/current/spring-framework-
reference/core.html#validation-beanvalidation-
overview)であり、そちらのリファレンスに[独自制約の実装方法も解説されています](https://docs.jboss.org/hibernate/validator/6.0/reference/en-
US/html_single/#validator-customconstraints)。

以下、このリファレンスに書かれていることほぼそのままになりますが具体的な実装手順です。

まず`@Pattern`に代わる独自のアノテーションを作成します:

[code]

    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE })
    @Retention(RUNTIME)
    @Constraint(validatedBy = OroPatternValidator.class)
    @Documented
    @Repeatable(OroPattern.List.class)
    public @interface OroPattern {
    
        String message() default "Mismatch pattern.";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
        String value();
    
        @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
            OroPattern[] value();
        }
    }
    
[/code]

次にこれに対応するバリデータを作成します。ここでOROを使ったvalidationを行います(※OROについて詳しくないで実装は適当です):

[code]

    public class OroPatternValidator implements ConstraintValidator<OroPattern, String> {
    
        private PatternMatcher matcher;
        private Pattern pattern;
    
        @Override
        public void initialize(final OroPattern constraintAnnotation) {
            matcher = new Perl5Matcher();
            try {
                this.pattern = new Perl5Compiler().compile(constraintAnnotation.value());
            } catch (final MalformedPatternException e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public boolean isValid(final String value, final ConstraintValidatorContext constraintContext) {
            return matcher.matches(value, pattern);
        }
    }
    
[/code]

上で作成した
`@OroPattern`アノテーションを`@Pattern`の代わりに付与することで、`OroPatternValidator`での検証が行えます。

[code]

    public class MyParam {
        @OroPattern("\\d{2}")
        private String value;
    }
    
[/code]

* * *

[Spring Bootですが実装サンプル](https://github.com/yukihane/stackoverflow-
qa/tree/master/so60029)


CC BY-SA 4.0
2019-10-29T09:11:05.677
60071
2019-10-29T09:11:05.677
2808
60029
answer