Java 使用CXF对JAX-RS子资源进行Bean验证

Java 使用CXF对JAX-RS子资源进行Bean验证,java,jax-rs,cxf,bean-validation,Java,Jax Rs,Cxf,Bean Validation,我尝试将RESTAPI与ApacheCXF一起使用。我读过,它对根资源很有效,但对根资源不起作用。子资源的约束将被忽略 Maven依赖项: org.apache.cxf 但两者都是关于返回值的验证,而不是关于请求参数的验证 这个问题是类似的,但关于卡拉夫和蓝图,并没有解决我的问题 我认为bean验证不会在子资源上工作,请参阅的源代码,它由jaxrsbeanvalidationinterceptor扩展,并用作验证拦截器。如果注意到方法handleValidation,很明显,验证是在资源

我尝试将RESTAPI与ApacheCXF一起使用。我读过,它对根资源很有效,但对根资源不起作用。子资源的约束将被忽略

Maven依赖项:


org.apache.cxf

  • 但两者都是关于返回值的验证,而不是关于请求参数的验证


    这个问题是类似的,但关于卡拉夫和蓝图,并没有解决我的问题

    我认为bean验证不会在子资源上工作,请参阅的源代码,它由
    jaxrsbeanvalidationinterceptor
    扩展,并用作验证拦截器。如果注意到方法
    handleValidation
    ,很明显,验证是在资源对象的参数上进行的。现在,此验证发生在对资源调用实际服务方法之前(至少看起来是这样),此时子资源实例未知(不存在),因此通常无法验证此时的子资源参数

    我的印象是,使用正在讨论的CXF中的当前机制(拦截器),子资源参数可能无法以正常方式进行bean验证

    您可能会采取一种变通方法,参考,您可以尝试手动验证参数(特别是如果它是请求JSON),即实例化验证器对象,然后使用该对象进行验证,例如

    package validator;
    
    import java.util.Set;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.Validation;
    import javax.validation.Validator;
    import javax.validation.ValidatorFactory;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Pattern;
    
    import org.apache.bval.jsr303.ApacheValidationProvider;
    
    public class DataBean {
    
        @Max(10)
        public int x = 0;
    
        @Pattern(regexp= "this_string")
        public String y =  "this_string"; // also matches null
    
        public static void main(String[] args) {
    
            ValidatorFactory avf =
                Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();
    
            DataBean bean = new DataBean();
            Validator validator = avf.getValidator();
    
            Set<ConstraintViolation<DataBean>> violations = validator.validate(bean);
    
            System.out.println(violations);
        }
    
    } // calss closing
    
    包验证程序;
    导入java.util.Set;
    导入javax.validation.ConstraintViolation;
    导入javax.validation.validation;
    导入javax.validation.Validator;
    导入javax.validation.ValidatorFactory;
    导入javax.validation.constraints.Max;
    导入javax.validation.constraints.NotNull;
    导入javax.validation.constraints.Pattern;
    导入org.apache.bval.jsr303.ApacheValidationProvider;
    公共类数据库{
    @最多(10)
    公共整数x=0;
    @模式(regexp=“此字符串”)
    public String y=“this_String”;//也匹配null
    公共静态void main(字符串[]args){
    验证器工厂avf=
    Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();
    DataBean=newDataBean();
    Validator Validator=avf.getValidator();
    设置冲突=validator.validate(bean);
    系统输出打印(违规);
    }
    }//计算关闭
    
    我想说的是,定制调用程序是一条出路。但根据你的评论,我想你已经知道了

    
    
    我在你的例子上试过了,效果很好。但是我认为您需要使用一个
    异常apper
    ,因为您没有得到正确的异常。我认为
    ValidationExceptionMapper
    将是正确的选择

    编辑-根据注释更新异常映射器类

    package validator;
    
    import java.util.Set;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.Validation;
    import javax.validation.Validator;
    import javax.validation.ValidatorFactory;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Pattern;
    
    import org.apache.bval.jsr303.ApacheValidationProvider;
    
    public class DataBean {
    
        @Max(10)
        public int x = 0;
    
        @Pattern(regexp= "this_string")
        public String y =  "this_string"; // also matches null
    
        public static void main(String[] args) {
    
            ValidatorFactory avf =
                Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory();
    
            DataBean bean = new DataBean();
            Validator validator = avf.getValidator();
    
            Set<ConstraintViolation<DataBean>> violations = validator.validate(bean);
    
            System.out.println(violations);
        }
    
    } // calss closing