繁体   English   中英

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

[英]Bean validation for JAX-RS sub resource with CXF

我尝试将Bean Validation用于我的REST API与Apache CXF。 我阅读了Apache CXF文档 ,它适用于根资源,但它不适用于子资源定位器 子资源会忽略约束。

Maven依赖:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    <version>3.1.5</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.apache.bval</groupId>
    <artifactId>bval-jsr</artifactId>
    <version>1.1.0</version>
</dependency>

Java代码:

@Named
@Path("test")
public class TestResource {

    @Inject
    private TestSubResource subResource;

    @Path("sub")
    public TestSubResource getSubResource() {
        return subResource;
    }

    @GET
    public void find(@NotNull @QueryParam("value") String value) {
    }
}

@Named
public class TestSubResource {

    @GET
    public void find(@NotNull @QueryParam("value") String value) {
    }
}

CXF配置:

<bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider" />
<bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
    <property name="provider" ref="validationProvider" />
</bean>
<jaxrs:server address="/rest" id="test" staticSubresourceResolution="true">
    <jaxrs:serviceBeans>
        <ref bean="testResource" />
    </jaxrs:serviceBeans>
    <jaxrs:inInterceptors>
        <ref bean="validationInInterceptor" />
    </jaxrs:inInterceptors> 
</jaxrs:server>

我发现了以下问题:

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

Karaf中的问题CXF:如何在子资源上配置bean验证(最好使用Blueprint)? 是类似的,但关于卡拉夫和蓝图,并没有解决我的问题。

我会说自定义调用程序是要走的路。 但我想你已经根据你的评论知道了。

<bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider" />
<bean id="validationInInterceptor"
    class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
    <property name="provider" ref="validationProvider" />
</bean>
<bean id="validationInvoker" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInvoker"></bean>

<jaxrs:server address="/rest" id="test"
    staticSubresourceResolution="true">
    <jaxrs:serviceBeans>
        <ref bean="testResource" />
    </jaxrs:serviceBeans>
    <jaxrs:inInterceptors>
        <ref bean="validationInInterceptor" />
    </jaxrs:inInterceptors>
    <jaxrs:invoker>
        <ref bean="validationInvoker" />
    </jaxrs:invoker>
</jaxrs:server>

我在你的例子上尝试过,它确实有效。 但我认为你需要使用ExceptionMapper ,因为你没有得到适当的例外。 我认为ValidationExceptionMapper是正确的。

编辑 - 基于注释更新了异常映射器类

我认为bean验证不会BeanValidationInInterceptor资源起作用,请参考BeanValidationInInterceptor的源代码,它由JAXRSBeanValidationInInterceptor扩展并用作验证拦截器。 如果您注意到方法handleValidation ,则很明显验证发生在资源对象的参数上。 现在,这个验证是在资源上调用实际服务方法之前发生的(至少它是如何查看的),此时,子资源实例是未知的(不存在),所以一般来说,这里的子资源参数关节无法验证。

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

你可以采取一种解决方法,参考JAX-RS参考 ,你可以尝试bean验证参数(特别是如果它是一个请求JSON),手动即实例化Validator对象,然后用它验证它,例如

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM