是否有 'choice' Java 注释等同于 <xs:choice>?
Is there a 'choice' Java annotation equivalent to <xs:choice>?
我希望通过仅允许请求中的两个不同字段之一来对 Web 服务请求进行现场验证。我从过去使用 xsd 的经验中知道,你可以有这样的东西只允许 FieldOne 或 FieldTwo:
<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)。
有什么东西可以用来 'choice' 吗?
感谢您的帮助。
更新: 基本上我正在寻找某种方法,只允许在 Web 服务请求中输入两个不同字段之一,而无需在我的代码中手动执行此验证.我目前正在使用 bean validation annotations 来限制字段长度并确定字段是必填字段还是可选字段,例如:
@NotNull(message="Field cannot be empty")
@Size(max = 6, message = "Field length is too long")
private String fieldOne;
我想说的是,用户只能输入 fieldOne 或 fieldTwo,但不能同时输入。这可以通过注释实现,还是我坚持在我的代码中编写此验证?
已编辑:
要验证其中一个字段是否有值,我认为您可以在 class 级别使用自定义验证器。以下是思路:
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
的实现以检查要验证的值是否在 Choice
注释内的 fields
中:
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;
}
原文:
我不确定我是否真的理解您的意思,但看起来您想要对 Object
字段的 Class
类型进行验证。如果是这种情况,您可以尝试创建自定义注释并 ConstraintValidator
这样做。以下是思路:
1。
为您的注释创建界面:
public @interface Choice {
Class<?>[] types();
}
2。
创建 ConstraintValidator
的实现以检查要验证的值是否在 Choice
注释内的 types
中:
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;
}
希望对您有所帮助。
我希望通过仅允许请求中的两个不同字段之一来对 Web 服务请求进行现场验证。我从过去使用 xsd 的经验中知道,你可以有这样的东西只允许 FieldOne 或 FieldTwo:
<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)。
有什么东西可以用来 'choice' 吗?
感谢您的帮助。
更新: 基本上我正在寻找某种方法,只允许在 Web 服务请求中输入两个不同字段之一,而无需在我的代码中手动执行此验证.我目前正在使用 bean validation annotations 来限制字段长度并确定字段是必填字段还是可选字段,例如:
@NotNull(message="Field cannot be empty")
@Size(max = 6, message = "Field length is too long")
private String fieldOne;
我想说的是,用户只能输入 fieldOne 或 fieldTwo,但不能同时输入。这可以通过注释实现,还是我坚持在我的代码中编写此验证?
已编辑:
要验证其中一个字段是否有值,我认为您可以在 class 级别使用自定义验证器。以下是思路:
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
的实现以检查要验证的值是否在 Choice
注释内的 fields
中:
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;
}
原文:
我不确定我是否真的理解您的意思,但看起来您想要对 Object
字段的 Class
类型进行验证。如果是这种情况,您可以尝试创建自定义注释并 ConstraintValidator
这样做。以下是思路:
1。 为您的注释创建界面:
public @interface Choice {
Class<?>[] types();
}
2。
创建 ConstraintValidator
的实现以检查要验证的值是否在 Choice
注释内的 types
中:
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;
}
希望对您有所帮助。