2016-07-05 2 views
0

Я ищу поле для проверки запроса веб-службы, разрешив только одно из двух полей запроса. Я знаю, что из прошлого опыта, с помощью XSD, что вы можете иметь что-то вроде этого, чтобы только либо FieldOne или FieldTwo:Есть ли «выбор» Java-аннотация, эквивалентная <xs:choice>?

<xs:complexType name="SomeType"> 
    <xs:choice> 
     <xs:element name="FieldOne" type="target:FieldOneType"/> 
     <xs:element name="FieldTwo" type="target:FieldTwoType"/> 
    </xs:choice> 
</xs:complexType> 

Я хотел бы сделать то же самое с помощью Java аннотаций. В настоящее время я использую аннотации для ограничения длины поля (@Digits) и нулевых проверок (@NotNull).

Есть ли что-то, что я могу использовать для «выбора»?

Спасибо за любую помощь.

UPDATE: В основном я ищу способ, которым можно ввести только одно из двух полей в запрос веб-службы без необходимости выполнять эту проверку в моем коде вручную. Я в настоящее время использую bean validation annotations ограничить длину поля и определить, является ли поле обязательным или необязательным, например:

@NotNull(message="Field cannot be empty") 
@Size(max = 6, message = "Field length is too long") 
private String fieldOne; 

Я хотел бы быть в состоянии сказать, что пользователь может ввести только либо fieldOne или fieldTwo, но не оба. Возможно ли это с помощью аннотаций или я придерживаюсь написания этой проверки в моем коде?

+0

Вы имеете в виду, что в вашем классе есть 2 поля ('fieldOne' и' fieldTwo'), но только один из них позволяет иметь значение? – Wilson

+0

Да, это то, чего я хочу. – colmulhall

+0

Я обновил ответ. Посмотрите, может ли он помочь – Wilson

ответ

1

Отредактировано:

Для проверки либо одно поле имеет значение, но не иначе, я думаю, что вы можете использовать собственный валидатор на уровне класса. Ниже идея:

1. Создать интерфейс для аннотации:

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = ChoiceValidator.class) 
@Documented 
public @interface Choice { 

    String[] fields(); 

    String message() default "{Choice.message}"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 

} 

2. Создать реализацию ConstraintValidator проверить значение, которое будет проверенным в fields внутри Choice аннотацию:

public class ChoiceValidator 
     implements ConstraintValidator<Choice, Object> { 

    private List<String> fields; 

    @Override 
    public void initialize(final Choice choice) { 
     fields = Arrays.asList(choice.fields()); 
    } 

    @Override 
    public boolean isValid(final Object value, final ConstraintValidatorContext ctx) { 

     int nonNullFieldCount = 0; 
     for (String field : fields) { 
      try { 
       final String fieldValue = BeanUtils.getProperty(value, field); 
       if (fieldValue != null) { 
        nonNullFieldCount++; 
       } 
      } catch (IllegalAccessException e) { 
       throw new RuntimeException(e); 
      } catch (InvocationTargetException e) { 
       throw new RuntimeException(e); 
      } catch (NoSuchMethodException e) { 
       throw new RuntimeException(e); 
      } 
     } 

     return nonNullFieldCount == 1; 
    } 

} 

После этого вы можете использовать его примерно так:

@Choice(fields= {"fieldOne", "fieldTwo"}) 
public class Foo { 

    String fieldOne; 

    String fieldTwo; 

} 

Оригинал:

Я не уверен, что я действительно получить вы имеете в виду, но выглядит, как вы хотите проверку на Class типах Object поля. Если это так, вы можете попытаться создать свою аннотацию и указать ConstraintValidator. Ниже идея:

1. Создать интерфейс для аннотации:

public @interface Choice { 

    Class<?>[] types(); 

} 

2. Создать реализацию ConstraintValidator проверить значение, которое будет подтверждено в types внутри Choice аннотацию:

public class ChoiceValidator implements ConstraintValidator<Choice, Object> { 

    private List<Class<?>> clazzes; 

    @Override 
    public void initialize(Choice choice) { 
     clazzes = Arrays.asList(choice.types()); 
    } 

    @Override 
    public boolean isValid(Object value, ConstraintValidatorContext context) { 
     for (Class<?> clazz : clazzes) { 
      if (value.getClass().equals(clazz)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

После этого, вы можете использовать что-то вроде:

@Choice(types = {FieldOneType.class, FieldTwoType.class}) 
public class Foo { 

    Object someType; 

} 

Надеется, что это может помочь.

+0

Спасибо за помощь. Это не совсем то, что я ищу, но это помогло мне лучше понять проблему. – colmulhall

+0

Можете ли вы предоставить более подробную информацию о своем требовании к вопросу? Это может помочь мне и другим придумать более подходящее решение. – Wilson

+0

Я добавил дополнительную информацию. Благодарю. – colmulhall

Смежные вопросы