2017-03-21 2 views
-1

カスタムアノテーションを書く(タイプレベルの注釈)方法を選択して検証することができます(いくつかのプロパティのうちの1つがヌルでない必要があります)?私はここでのコードの正確必要に応じて一枚持っているように@Notnull Springカスタム注釈バリデーション複数のフィールドを持つ

+0

実際の質問ではないのはなぜですか?(http://meta.stackoverflow.com/q/284236) – EJoshuaS

+1

[2つ以上のフィールドをどのように検証できますか?組み合わせ?](http://stackoverflow.com/questions/2781771/how-can-i-validate-two-or-more-fields-in-combination) –

答えて

2

この「質問」は非常に広い場合でも、私は答えを与える:

public class ChoiceValidator implements ConstraintValidator<Choice, Object> { 
    private String[] properties; 
    private boolean allowMultiple; 

    @Override 
    public void initialize(Choice constraintAnnotation) { 
     if (constraintAnnotation.value().length < 2) { 
      throw new IllegalArgumentException("at least two properties needed to make a choice"); 
     } 
     properties = constraintAnnotation.value(); 
     allowMultiple = constraintAnnotation.multiple(); 
    } 

    @Override 
    public boolean isValid(Object value, ConstraintValidatorContext context) { 
     try { 
      BeanInfo info = getBeanInfo(value.getClass()); 
      long notNull = Stream.of(properties) 
        .map(property -> Stream.of(info.getPropertyDescriptors()) 
          .filter(desr -> desr.getName().equals(property)) 
          .findAny() 
          .orElse(null) 
        ) 
        .map(prop -> getProperty(prop, value)) 
        .filter(Objects::nonNull) 
        .count(); 
      return allowMultiple ? notNull != 0 : notNull == 1; 
     } catch (IntrospectionException noBean) { 
      return false; 
     } 
    } 

    private Object getProperty(PropertyDescriptor prop, Object bean) { 
     try { 
      return prop.getReadMethod() == null ? null : prop.getReadMethod().invoke(bean); 
     } catch (ReflectiveOperationException noAccess) { 
      return null; 
     } 
    } 
} 
:ここ

@Target(ElementType.TYPE) 
@Retention(RUNTIME) 
@Documented 
@Constraint(validatedBy = ChoiceValidator.class) 
public @interface Choice { 
    String[] value(); 

    boolean multiple() default false; 

    String message() default "{com.stackoverflow.validation.Choice.message}"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 
} 

をBeanのプロパティへのアクセスを使用してバリデータ

@Data 
@Choice({"one", "two"}) 
class OneOf { 
    private String one; 
    private String two; 
    private String whatever; 
} 

@Data 
@Choice(value = {"one", "two"}, multiple = true) 
class AnyOf { 
    private String one; 
    private String two; 
} 

典型的な使い方は、(ゲッターとセッターを生成する注釈ロンボク島)のように見ることができます

しかし、明確にする:Stackoverflowは、開発者が知識を交換するためのQAコミュニティです。 "あなたは私のためにこれを無料でコードしてください"と尋ねる場所ではありません。すべての有益な貢献者は、まず問題を最初に解決しようとし、後に詳細な質問をします。質問に答える人々は余暇を過ごし、支払われません。将来的には、具体的な問題を尋ね、自分の努力を示して敬意を表してください。

+0

アルネありがとう! –

+0

@vinvinもしこれがあなたに有益なのであれば、アップアップのことを考えてみてください。 –

関連する問題