是否有一个';选择';Java注释相当于<;xs:choice>;?

是否有一个';选择';Java注释相当于<;xs:choice>;?,java,web-services,validation,xsd,annotations,Java,Web Services,Validation,Xsd,Annotations,我希望通过只允许请求中两个不同字段中的一个字段来验证web服务请求。我从过去使用xsd的经验中了解到,您可以有这样的功能,只允许FieldOne或FieldTwo: <xs:complexType name="SomeType"> <xs:choice> <xs:element name="FieldOne" type="target:FieldOneType"/> <xs:element name="FieldT

我希望通过只允许请求中两个不同字段中的一个字段来验证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>

我想说的是,用户只能输入fieldOne或fieldTwo,但不能同时输入两者。这是通过注释实现的还是我一直坚持在代码中编写验证?

编辑:

要验证其中一个字段是否有值,我认为可以在类级别使用自定义验证器。想法如下:

一,。 为注释创建界面:

@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 {};

}
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;
    }

}
public @interface Choice {

    Class<?>[] 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(fields= {"fieldOne", "fieldTwo"})
public  class Foo {

    String fieldOne;

    String fieldTwo;

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

    Object someType;

}

原件:

我不确定我是否真的明白你的意思,但看起来你想要对
对象的
类型进行验证。如果出现这种情况,您可以尝试创建自定义注释,并通过
ConstraintValidator
执行此操作。想法如下:

一,。 为注释创建界面:

@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 {};

}
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;
    }

}
public @interface Choice {

    Class<?>[] 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(fields= {"fieldOne", "fieldTwo"})
public  class Foo {

    String fieldOne;

    String fieldTwo;

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

    Object someType;

}

希望这能有所帮助。

谢谢你的帮助。这并不是我想要的,但它帮助我更好地理解这个问题。你能提供更多关于你对这个问题的要求的细节吗?这可能会帮助我和其他人想出一个更合适的解决方案。太好了,谢谢你在这方面的工作。这就解决了我的问题:)你是说你们班有两个字段(
fieldOne
fieldTwo
),但其中只有一个允许有值吗?是的,这就是我想要的。我已经更新了答案。请看它是否有帮助