当前位置: 首页 > 知识库问答 >
问题:

用于Bean验证的Jersey扩展是否支持Bean验证2.0(JSR380)

柳豪
2023-03-14

我正在使用WebSphere Liberty 19.0.0.2和WebProfile-8.0特性,该特性支持JAXRS-2.1和BeanValidation-2.0。为了更好地支持多部分流,我使用Jersey作为JAX-RS实现,而不是Liberty的默认Apache CXF。

有关相关组件版本控制的一些更多上下文信息

Bean验证1.1(JSR 349)、Bean验证2.0(JSR 380)

compile group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.30'

[3/5/20 18:11:28:597 EST] 00000020 id=00000000 org.glassfish.jersey.model.Parameter                         2 Unable to get the com.sun.proxy.$Proxy70 annotation value property
java.lang.NoSuchMethodException: javax.validation.constraints.NotNull.value()
    at java.lang.Class.getMethod(Class.java:1786)
    at org.glassfish.jersey.model.Parameter.getValue(Parameter.java:453)
    at org.glassfish.jersey.model.Parameter.create(Parameter.java:270)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:400)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:383)
    at org.glassfish.jersey.server.model.Parameter.create(Parameter.java:137)
    at org.glassfish.jersey.server.model.Invocable.<init>(Invocable.java:215)
    at org.glassfish.jersey.server.model.Invocable.create(Invocable.java:161)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.createInvocable(ResourceMethod.java:541)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.build(ResourceMethod.java:522)
    at org.glassfish.jersey.server.model.Resource$Builder.processMethodBuilders(Resource.java:647)
    at org.glassfish.jersey.server.model.Resource$Builder.buildResourceData(Resource.java:583)
    at org.glassfish.jersey.server.model.Resource$Builder.build(Resource.java:639)
    at org.glassfish.jersey.server.model.Resource.from(Resource.java:782)
    at org.glassfish.jersey.server.ResourceBagConfigurator.init(ResourceBagConfigurator.java:55)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:331)
    at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:293)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:292)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:259)
    at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
    at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:347)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:291)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1373)
    at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:1157)
    at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:1125)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1023)
    at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6619)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:467)
    at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:462)
    at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1152)
    at com.ibm.ws.webcontainer.osgi.WebContainer.access$000(WebContainer.java:111)
    at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:957)
    at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:239)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

[3/5/20 18:11:28:598 EST] 00000020 id=00000000 org.glassfish.jersey.model.Parameter                         2 Unable to get the com.sun.proxy.$Proxy29 annotation value property
java.lang.NoSuchMethodException: javax.validation.Valid.value()
    at java.lang.Class.getMethod(Class.java:1786)
    at org.glassfish.jersey.model.Parameter.getValue(Parameter.java:453)
    at org.glassfish.jersey.model.Parameter.create(Parameter.java:270)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:400)
    at org.glassfish.jersey.model.Parameter.createList(Parameter.java:383)
    at org.glassfish.jersey.server.model.Parameter.create(Parameter.java:137)
    at org.glassfish.jersey.server.model.Invocable.<init>(Invocable.java:215)
    at org.glassfish.jersey.server.model.Invocable.create(Invocable.java:161)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.createInvocable(ResourceMethod.java:541)
    at org.glassfish.jersey.server.model.ResourceMethod$Builder.build(ResourceMethod.java:522)
    at org.glassfish.jersey.server.model.Resource$Builder.processMethodBuilders(Resource.java:647)
<featureManager>
    <!--NOTE: Following are standard features and should not be removed-->
    <feature>servlet-4.0</feature>
    <feature>jndi-1.0</feature>
    <feature>requestTiming-1.0</feature>
    <feature>monitor-1.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>restConnector-2.0</feature>
    <feature>ssl-1.0</feature>

    <!-- Do not add enabled webProfile-8.0 because we want to disable default 
    REST implementation (Apache-CXF) provided by Liberty. We want to use Jersey 
    as our REST implementation because it better support multi-part streaming, -->
    <!-- <feature>webProfile-8.0</feature> -->
    <feature>jsp-2.3</feature>
    <feature>cdi-2.0</feature>
    <feature>managedBeans-1.0</feature>
    <feature>jdbc-4.2</feature>
    <feature>beanValidation-2.0</feature>
    <!-- We need javaMail feature for logback email appender to work -->
    <feature>javaMail-1.6</feature>
</featureManager>

下面是扩展Jersey的ResourceConfig类的rest应用程序配置

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;

@ApplicationPath("/rest")
public class RestApplicationConfig extends ResourceConfig {

    public RestApplicationConfig() {
        super();
        configureResourcesAndFeatures();
    }

    private void configureResourcesAndFeatures() {
        packages(RestApplicationConfig.class.getPackage().getName());
        register(MultiPartFeature.class);

        property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
    }
}

我提到了jersey-bean-validation版本2.30的使用,但我了解到Jersey2.27是最新版本,是JAX-RS2.1API的JAVA EE实现。从2.28开始,JAX-RS2.1的雅加达EE实现。因此,我真的想使用2.27版本,并使bean验证2.0与它一起工作,因为我使用的liberty版本还没有达到jakarta ee。

共有1个答案

韦锦程
2023-03-14

所有问题的原因是jersey-bean-validation jar中打包的META-INF信息不正确,以及gradle依赖项也不正确。

您必须排除以上不正确的传递依赖关系,并包含Bean验证2.0(JSR380)的正确版本,即Hibernate Validator6.0(6.0.18.final)

如果容器已经提供了bean验证的实现,则不需要包含hibernate validator JAR。在我的例子中,启用了liberty中的BeanValidation-2.0,它提供了bean验证实现。

// Jersey 2.27 is latest version which is JAVA EE implementation of JAX-RS 2.1 API. Starting 2.28 its Jakarta EE implementation of JAX-RS 2.1
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.27'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.27'
compile (group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '2.27') {
    exclude group: 'javax.inject', module: 'javax.inject'
}
compile (group: 'org.glassfish.jersey.ext', name: 'jersey-bean-validation', version: '2.27') {
    exclude group: 'javax.el', module: 'javax.el-api'
    exclude group: 'org.hibernate'
}

configurations.compile {
    exclude group: 'javax.validation', module: 'validation-api'
    exclude group: 'javax.annotation', module: 'javax.annotation-api'
}
 类似资料:
  • 我使用gradle和以下libs:

  • 在Bean验证规范(JSR303和JSR349)和文档中,都没有提到@digits对Double或Float类型的支持。它只说支持以下类型: BigDecimal BigInteger CharSequence 字节、short、int、long及其各自的包装器类型

  • 我正在尝试使用自定义Bean验证来验证应该大于零的数值,但问题是使用如下单个自定义验证器来验证任何数值:整数、浮点数、双......: 整数int; @PositiveNumber双倍双; 这可能吗?

  • 对于错误的响应,是否可能在响应中返回验证注释消息?我认为这是可能的,但我注意到我们的项目没有给出详细的不良请求信息。 如果请求缺少IDField,我希望返回“IDField is required”。我用的是泽西2.0。我看到的回应是...

  • 使用krasa-jaxb-tools jaxb-plugin,我生成了以下内容: 来自XSD架构: 我得到了注释元素: 使用JAXB,我成功地生成了有效的XML(它通过了XSD验证--包括上面提到的字符串的格式)。 但是,如果我尝试使用Bean验证验证上面提到的字符串,它会抛出错误--如果它被写为“small123”,它会说它应该大写(失败small.123[a-za-z0-9.]{0,27}re

  • 环境 Glassfish 3.1.2内置Hibernate-Validator 4.2。