第 5 章 Quarkus CXF 用户指南
本章提供有关 Quarkus CXF 用法和配置的信息。
5.1. 用户指南 复制链接链接已复制到粘贴板!
此用户指南解释了 Quarkus CXF 的典型用例。
您可能想要从以下一些主题开始:
5.1.1. 创建新项目 复制链接链接已复制到粘贴板!
本指南介绍了如何为托管 CXF 客户端或服务器或两者的 Quarkus 应用程序设置新项目。
5.1.1.1. 先决条件 复制链接链接已复制到粘贴板!
请参阅 Quarkus 入门指南 的先决条件部分。
除此之外,您可能需要
-
安装了
native-image命令以及GRAALVM_HOME环境变量集的 GraalVM。请参阅 Quarkus 文档中的 构建原生可执行文件 部分。 -
如果您在 Linux 上,如
docker的容器运行时也足以满足原生模式。如果选择这个选项,则使用-Pnative -Dquarkus.native.container-build=true而不是-Pnative。
5.1.1.2. 创建一个项目 复制链接链接已复制到粘贴板!
可以使用 code.quarkus.redhat.com 生成新项目框架。
- 您可以在此处选择您要使用的扩展。
-
对于简单的 Hello world Web 服务或客户端,
quarkus-cxf扩展就足够了。 -
单击 blue
Generate your application按钮,以下载基本的框架项目。 - 解包 zip 文件,并将项目 导入到您首选的 IDE 中。
5.1.1.3. Quarkus 平台 复制链接链接已复制到粘贴板!
Quarkus CXF 是 Quarkus Platform 版本 3.1.0.Final 的一部分。
Quarkus 平台聚合了由各种独立项目生成的 Quarkus 扩展,如 Quarkus Core、Quarkus CXF、Apache Camel、Qpid JMS、Debezium 等。
其主要目标是:
- 生成在所有参与项目间一致的 BOM,从而确保其扩展可以一起工作
- 生成 code.quarkus.redhat.com 和其他 Quarkus 开发工具 的元数据。
5.1.1.4. 依赖项管理 复制链接链接已复制到粘贴板!
我们建议使用 Quarkus Platform BOM 来管理 Quarkus CXF 依赖项。这是您获得的内容,当您使用 code.quarkus.redhat.com 或其他 Quarkus 开发工具 时,如 Quarkus CLI。
您应该始终谨慎将同一版本的 io.quarkus.platform:quarkus-bom 和 io.quarkus.platform:quarkus-cxf-bom 导入到项目中。这是获取 Quarkus、CXF、Pa Quarkus CXF 及其所有传输依赖项的最可靠方法。
5.1.1.5. 进入下一个位置 复制链接链接已复制到粘贴板!
我们建议使用以下任何章节:
5.1.2. Quarkus 上的第一个 SOAP Web 服务 复制链接链接已复制到粘贴板!
在本指南中,我们将说明如何创建 Quarkus 应用程序公开简单的 SOAP Web 服务。
在继续此处前,请按照 项目创建 指南操作。
5.1.2.1. 您好好!Web 服务 复制链接链接已复制到粘贴板!
将 pom.xml 已就绪,您可以添加一个简单的 Hello world!src/main/java 中的 Web 服务.
本节中使用的代码片段示例来自 Quarkus CXF 源树中的服务器 集成测试
首先添加服务接口:
HelloService.java
然后实现:
HelloServiceImpl.java
要使在特定路径下公开的实现,您需要将以下配置添加到 application.properties 中:
所有配置属性都记录在 配置属性参考 中。
检查 服务端点和路径 章节,以了解在特定路径下公开服务端点的替代方法。
使用这些文件,您可以在 dev 模式中启动 Quarkus:
mvn quarkus:dev
$ mvn quarkus:dev
这将编译项目,并在后台启动应用程序。
您可以使用 curl 或其它 SOAP 客户端测试服务。
首先,让我们在 http://localhost:8080/soap/hello?wsdl 下查看自动生成的 WSDL:
其次,让我们向服务发送 SOAP 请求:
您可以在 SOAP 响应中看到预期的 & lt;return>Hello World!</return >。
5.1.2.2. 在 dev 模式运行时添加日志记录功能 复制链接链接已复制到粘贴板!
有时,可以方便检查由服务器或客户端接收或发送的 SOAP 消息。这可以通过将 quarkus-cxf-rt-features-logging 扩展添加到 pom.xml 来轻松实现。
尝试在 Quarkus dev 模式运行时执行此操作。您应该会在源树中保存更改时重新编译并重新部署应用程序。
将其添加到 pom.xml
<dependency>
<groupId>io.quarkiverse.cxf</groupId>
<artifactId>quarkus-cxf-rt-features-logging</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.cxf</groupId>
<artifactId>quarkus-cxf-rt-features-logging</artifactId>
</dependency>
在 application.properties中启用 SOAP 有效负载日志记录
quarkus.cxf.endpoint."/hello".features=org.apache.cxf.ext.logging.LoggingFeature
quarkus.cxf.endpoint."/hello".features=org.apache.cxf.ext.logging.LoggingFeature
在发送一个新的 SOAP 请求并在应用程序控制台中看到一些 SOAP 有效负载后:
5.1.2.3. 进一步的步骤 复制链接链接已复制到粘贴板!
您可能希望继续打包应用程序,以便在 JVM 上运行或原生运行。
5.1.3. Quarkus 上的第一个 SOAP 客户端 复制链接链接已复制到粘贴板!
在本指南中,我们解释了如何创建充当远程 Web 服务客户端的简单 Quarkus 应用程序。
在继续此处前,请按照 项目创建 指南操作。
5.1.3.1. 用于测试的远程 Web 服务 复制链接链接已复制到粘贴板!
首先,我们需要一些远程 Web 服务来连接。我们可以使用一个在容器中运行的简单 计算器 Web 服务 来实现这一目的。
docker run -p 8082:8080 quay.io/l2x6/calculator-ws:1.0
$ docker run -p 8082:8080 quay.io/l2x6/calculator-ws:1.0
容器启动并运行后,我们可以检查其 WSDL
正如您在 WSDL 中看到的那样,该服务提供一些基本的算术操作,如添加、减去 等。
我们使用 curl 测试它:
5.1.3.2. SOAP 客户端 复制链接链接已复制到粘贴板!
现在,让我们来看看如何在 Quarkus 应用程序中获取客户端。
首先,我们需要服务端点接口(SEI)以及它所需的所有所有其他模型类。
获取它们的方法有几种:
- 手动写入
- 使用 Java 编写 Web Sevice 项目复制
- 具有包含模型类的 Maven 工件,可能由 Service 项目提供
- 从 WSDL 生成模型类
最后一个选项往往是客户端应用程序最简单且最灵活的选项。
如果要使用这种方法,请首先遵循 从 WSDL 部分中生成 Java,然后继续后续步骤。
5.1.3.3. 使用 SEI 作为客户端 复制链接链接已复制到粘贴板!
在我们的情形中,Service Endpoint Interface (SEI)是 org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService。
在 Quarkus 中,我们可以通过 CDI 获取其实例。
为了便于测试,我们将将其嵌套在 REST 服务中:
CxfClientResource.java
除了上述之外,我们是否需要使用此功能?- 除了上述之外,我们需要向 application.properties 中的 CXF Quarkus 扩展告知其他内容:
application.properties
cxf.it.calculator.baseUri=http://localhost:8082
quarkus.cxf.client.myCalculator.wsdl = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService?wsdl
quarkus.cxf.client.myCalculator.client-endpoint-url = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService
quarkus.cxf.client.myCalculator.service-interface = org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService
cxf.it.calculator.baseUri=http://localhost:8082
quarkus.cxf.client.myCalculator.wsdl = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService?wsdl
quarkus.cxf.client.myCalculator.client-endpoint-url = ${cxf.it.calculator.baseUri}/calculator-ws/CalculatorService
quarkus.cxf.client.myCalculator.service-interface = org.jboss.eap.quickstarts.wscalculator.calculator.CalculatorService
所有客户端配置属性都记录在 配置属性参考 中。
对于以上所有文件,我们应当能够在 Quarkus dev 模式中启动应用程序
mvn quarkus:dev ... INFO [io.quarkus] (Quarkus Main Thread) ... Listening on: http://localhost:8080
$ mvn quarkus:dev
...
INFO [io.quarkus] (Quarkus Main Thread) ... Listening on: http://localhost:8080
并通过向它发送一些请求来测试它:
curl -s 'http://localhost:8080/cxf/calculator-client/add?a=5&b=6' 11
$ curl -s 'http://localhost:8080/cxf/calculator-client/add?a=5&b=6'
11
其中 11 是添加 5 和 6 的正确结果。
5.1.3.4. 进一步的步骤 复制链接链接已复制到粘贴板!
您可能需要继续
5.1.4. 配置 复制链接链接已复制到粘贴板!
Quarkus CXF 会公开大量配置选项。每个扩展都会在其 参考页面底部 记录了其选项。
配置选项可以在 application.properties 文件中设置,或者通过环境变量设置 - 请参阅 Quarkus 配置参考。
5.1.4.1. Bean 引用 复制链接链接已复制到粘贴板!
Quarkus CXF 的多个配置选项允许引用 Quarkus CDI 容器中出现的 Bean。功能和拦截器 是它们的典型示例。
可以通过两种方式在配置中设置 bean 引用:根据类型或 bean 名称。
5.1.4.1.1. 根据类型进行 bean 引用 复制链接链接已复制到粘贴板!
下面是一个示例:
application.properties
bean reference by type quarkus.cxf.endpoint."/hello".features = org.apache.cxf.ext.logging.LoggingFeature
# bean reference by type
quarkus.cxf.endpoint."/hello".features = org.apache.cxf.ext.logging.LoggingFeature
当使用按类型名称的引用时,解析进行如下:
- 按照类型在 Quarkus CDI 容器中查找 bean。
- 如果 bean 可用,则会使用它。
- 如果多个 Bean 分配给给定类型,则抛出异常。
- 如果没有匹配的 bean 可用,则会加载类并执行尝试以使用其默认构造器实例化它。
5.1.4.1.2. Bean 名称引用 复制链接链接已复制到粘贴板!
下面是一个示例:
application.properties
bean reference by bean name quarkus.cxf.endpoint."/fruit".features = #myCustomLoggingFeature
# bean reference by bean name
quarkus.cxf.endpoint."/fruit".features = #myCustomLoggingFeature
使用 bean 名称的引用时,记者会按名称查找 Quarkus CDI 容器。名为 myCustomLoggingFeature 的命名 Bean 可以定义如下:
5.1.5. 用于在 JVM 或原生运行的软件包 复制链接链接已复制到粘贴板!
在本章中,我们解释了如何打包 Quarkus CXF 应用程序,以便在 JVM 上运行或原生运行它。
5.1.5.1. JVM 模式 复制链接链接已复制到粘贴板!
在 SOAP 客户端和 SOAP 服务的入门指南中,我们只在 Quarkus dev mode: Quarkus 工具中工作,在后台监视工作区的更改,根据需要重新编译并重新载入应用程序。
我们使用开发完成后,如何在 JVM 上运行应用程序?
首先,我们需要使用 Maven 打包它:
mvn package
$ mvn package
在 JVM 上运行应用程序所需的库可在 target/quarkus-app 目录中找到:
我们可以按如下所示启动应用程序:
java -jar target/quarkus-app/quarkus-run.jar
$ java -jar target/quarkus-app/quarkus-run.jar
您可以使用 curl 发送一些 SOAP 请求,以确保应用程序正常工作。
5.1.5.2. 原生模式 复制链接链接已复制到粘贴板!
Quarkus 为构建 GraalVM 原生镜像和 Quarkus CXF 完全遵循的类支持。
GraalVM 原生镜像是平台特定的可执行文件,您可以在没有 JVM 的情况下直接运行。与在 JVM 模式下运行相同的应用相比,它们启动速度更快,且内存更少。
code.quarkus.redhat.com 生成的 pom.xml 文件包含构建 原生 镜像所需的原生配置集:
此外,如 第 5.1.1 节 “创建新项目” 部分所述,您需要 GraalVM native-image 工具。
您应该在本地安装它,并有正确设置 GRAALVM_HOME 环境变量,或者需要生成 Linux 原生的可执行文件 swig-mvapich,您可以使用 docker。
使用本地安装 GraalVM
Quarkus 对 GraalVM 版本非常自选。使用本地安装时,请务必使用 Quarkus 首选版本。为此,您可以打开 pom.xml 中导入的 quarkus-bom,并在其中搜索 graalvm。如果使用 Docker,Quarkus 会为您拉取正确的版本。
使用 docker
# Produce the native executable mvn package -Pnative -Dquarkus.native.container-build=true
# Produce the native executable
mvn package -Pnative -Dquarkus.native.container-build=true
对于简单的应用程序,这可能需要一分钟的时间。
构建完成后,原生可执行文件应 在目标目录中 可用:
ls -l target ... -rwxr-xr-x. 1 ppalaga ppalaga 71M Jan 11 22:42 quarkus-cxf-integration-test-server-1.8.0-SNAPSHOT-runner ...
$ ls -l target
...
-rwxr-xr-x. 1 ppalaga ppalaga 71M Jan 11 22:42 quarkus-cxf-integration-test-server-1.8.0-SNAPSHOT-runner
...
正如您所见,它的大小只能为 71 MB,并且是可执行的。
您可以按照以下方式运行它:
target/*-runner ... INFO [io.quarkus] (main) quarkus-cxf-integration-test-server 1.8.0-SNAPSHOT native (powered by Quarkus 2.15.2.Final) started in 0.042s. Listening on: http://0.0.0.0:8080 ...
$ target/*-runner
...
INFO [io.quarkus] (main) quarkus-cxf-integration-test-server 1.8.0-SNAPSHOT native (powered by Quarkus
2.15.2.Final) started in 0.042s. Listening on: http://0.0.0.0:8080
...
同样,您可以使用 curl 发送一些 SOAP 请求,以确保原生可执行文件正常工作。
不要忘记比较内存用量、第一次请求和其他性能指标与您前面使用的堆栈进行比较,并共享结果!
5.1.5.3. 原生镜像:附加资源 复制链接链接已复制到粘贴板!
您还可以参考以下链接,其中包含有关如何处理原生镜像的提示。
5.1.5.4. 创建容器镜像 复制链接链接已复制到粘贴板!
请参阅 Quarkus 容器镜像 指南。
5.1.6. 日志记录 复制链接链接已复制到粘贴板!
有关 Quarkus 上日志记录的基本信息,请参阅 Quarkus Logging 指南,例如
5.1.6.1. 有效负载日志记录 复制链接链接已复制到粘贴板!
从 Quarkus CXF 2.6.0 开始,有效负载日志记录功能可以通过 io.quarkiverse.cxf:quarkus-cxf 扩展提供。在 2.6.0 之前,它可以通过单独的扩展 io.quarkiverse.cxf:quarkus-cxf-rt-features-logging 提供,它将在以后的版本中删除。
有效负载日志记录功能主要通过 org.apache.cxf.ext.logging.LoggingFeature 类实现。
您可以通过几种方法在客户端或服务端点上设置该功能。
5.1.6.2. 通过配置属性配置有效负载日志记录 复制链接链接已复制到粘贴板!
5.1.6.2.1. 全局设置 复制链接链接已复制到粘贴板!
自 Quarkus CXF 2.6.0 开始存在全局日志记录选项。它们需要使用 quarkus.cxf.logging.enabled-for 启用。有四个可能的值:
-
none(默认)- 没有为客户端和服务端点启用全局日志记录功能 -
客户端- 为应用程序中的所有客户端启用全局日志记录功能 -
服务- 为应用程序中的所有服务端点启用全局日志记录功能 -
两者都为应用程序中的所有客户端和服务端点启用全局日志记录功能
全局设置可以在 客户端或 服务端点级别上覆盖。
application.properties
# Global settings quarkus.cxf.logging.enabled-for = both quarkus.cxf.logging.pretty = true
# Global settings
quarkus.cxf.logging.enabled-for = both
quarkus.cxf.logging.pretty = true
所有日志记录配置选项都列在 quarkus-cxf 参考页面中。
本页中提到的所有日志记录属性都是 运行时 配置选项。因此,您可以在启动应用程序时传递它们,而无需重新构建它。它可以通过在命令行中传递系统属性(例如,-Dquarkus.cxf.logging.enabled-for=both)或设置环境变量(例如,导出 QUARKUS_CXF_LOGGING_ENABLED_FOR=both)。
5.1.6.2.2. 每个客户端和每个服务端点设置 复制链接链接已复制到粘贴板!
从 Quarkus CXF 2.5.0 开始,可以通过在 application.properties 中设置适当的选项来声明性地配置并附加到客户端或服务端点:
application.properties
所有日志记录配置选项都记录在 quarkus-cxf 参考页面中:
5.1.6.3. 将 LoggingFeature 添加到客户端或服务的替代方案 复制链接链接已复制到粘贴板!
要使用默认设置附加实例,您可以执行以下操作之一:
在
application.properties中:# For a service: quarkus.cxf.endpoint."/hello".features = org.apache.cxf.ext.logging.LoggingFeature # For a client: quarkus.cxf.client."myClient".features = org.apache.cxf.ext.logging.LoggingFeature
# For a service: quarkus.cxf.endpoint."/hello".features = org.apache.cxf.ext.logging.LoggingFeature # For a client: quarkus.cxf.client."myClient".features = org.apache.cxf.ext.logging.LoggingFeatureCopy to Clipboard Copied! Toggle word wrap Toggle overflow 提示用户指南 的第一 SOAP Web 服务 章节中有一个示例。
或者
使用 CXF 的
@Features注释:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.1.6.3.1. 生成自定义 LoggingFeature bean 复制链接链接已复制到粘贴板!
如果您需要一些自定义逻辑来设置 LoggingFeature,您可以生成名为 LoggingFeature bean :
然后,您可以使用其名称以 prefixed in application.properties 来引用它:
# For a service: quarkus.cxf.endpoint."/hello".features = #limitedLoggingFeature # For a client: quarkus.cxf.client.hello.features = #limitedLoggingFeature
# For a service:
quarkus.cxf.endpoint."/hello".features = #limitedLoggingFeature
# For a client:
quarkus.cxf.client.hello.features = #limitedLoggingFeature
5.1.7. 使用 JAXB 复杂的 SOAP 有效负载 复制链接链接已复制到粘贴板!
我们为 Quarkus SOAP 客户端和 SOAP 服务入门指南 处理仅有原语参数和返回值的服务,如整数和字符串。让我们来看一下传递和接收更复杂的对象。
例如,让我们创建用于管理有问题的应用程序。
本节中使用的代码片段示例来自 Quarkus CXF 源树中的服务器 集成测试
由于我们的混淆的表示应该比较复杂,因此让我们将其作为具有几个属性的 Java Bean 进行建模:
您可能已经注意到,我们使用了一些 JAXB 注释,如 @XmlElement、@XmlRootElement 和 @XmlType。这是为了控制 bean 从和 XML 序列化和反序列化。
5.1.7.1. 自动注册以反应 复制链接链接已复制到粘贴板!
JAXB 是一个基于反射的序列化框架。当学习 GraalVM 原生镜像时,您通常会听到的第一件事是在构建时注册类、字段和方法来反映。使用普通 GraalVM,您必须手动通过 reflection-config.json 来执行此操作。至少,对于您编写的类,至少要注意。不要使用 Quarkus。quarkus-jaxb 扩展(其 quarkus-cxf 依赖)能够扫描应用的类路径以获取带有 JAXB 注解的类类路径,并自动注册它们,以自动反映。
因此,在 Quarkus 上使用复杂有效负载与库存 CXF 不同。JAXB serialization 和 deserialization 将开箱即用,无需任何额外的配置。
5.1.7.2. SEI 和实现 复制链接链接已复制到粘贴板!
用于管理模糊的服务端点接口(SEI)可能类似如下:
我们可以根据需要实施 SEI:
5.1.7.3. application.properties 复制链接链接已复制到粘贴板!
实现非常简单,您只需要使用 application.properties 定义端点。
quarkus.cxf.endpoint."/fruits".implementor = io.quarkiverse.cxf.it.server.FruitServiceImpl quarkus.cxf.endpoint."/fruits".features = org.apache.cxf.ext.logging.LoggingFeature
quarkus.cxf.endpoint."/fruits".implementor = io.quarkiverse.cxf.it.server.FruitServiceImpl
quarkus.cxf.endpoint."/fruits".features = org.apache.cxf.ext.logging.LoggingFeature
5.1.7.4. 使用 Quarkus dev 模式和 curl测试 复制链接链接已复制到粘贴板!
使用上述文件,您可以在 dev 模式中启动 Quarkus 工具:
mvn quarkus:dev ... INFO [io.quarkus] (Quarkus Main Thread) ... Listening on: http://localhost:8080
$ mvn quarkus:dev
...
INFO [io.quarkus] (Quarkus Main Thread) ... Listening on: http://localhost:8080
然后,通过调用其 list 操作来检查该服务是否正常工作:
正如您所见,端点返回了默认情况下提供的两个 fruits Apple 和 Pineapple。
现在,让我们再添加另一个问题,表示一个 Orange :
我们可以看到 Orange 已如预期在返回的列表中添加。
5.1.7.5. 进一步的步骤 复制链接链接已复制到粘贴板!
您可能希望继续打包应用程序,以便在 JVM 上运行或原生运行。
5.1.8. 合同第一和代码第一种方法 复制链接链接已复制到粘贴板!
Quarkus CXF 完全支持第一个和代码第一个开发模式。
5.1.8.1. 合同第一个客户端 复制链接链接已复制到粘贴板!
WSDL 描述 SOAP 服务。它是定义操作的合同,其参数和返回值等。WSDL 足以生成完整客户端的代码。CXF 为其提供 wsdl2java 工具。
Quarkus CXF 将 wsdl2java 嵌套在 quarkus-cxf 扩展中,因此您不需要直接使用它。
按照用户指南 的 WSDL 部分中生成模型类,以了解更多有关如何使用它的详细信息。
您可能还想检查 CXF 开发一个 Consumer 作为一般简介。
5.1.8.2. 合同第一个服务 复制链接链接已复制到粘贴板!
在实施服务时,来自 WSDL 的 Java 代码 也可能会很方便。wsdl2java 可以为您生成模型类(带有 JAXB 注释)和服务接口(带有 JAX-WS 注释)。然后,您的任务是为这些接口提供实施。
您可能需要检查 CXF 文档中的 WSDL 第一服务开发 部分,以更好地了解底层概念。
5.1.8.3. 代码第一个服务 复制链接链接已复制到粘贴板!
您提出的另一个有效选项是使用 JAX-WS 和 JAXB 在 Java 中编写您的服务。然后,您有两个选择如何获取 WSDL 合同:
-
启动服务并将客户端指向
http://your-host/your-service?wsdl - 在构建时从 Java 类生成 WSDL 文档
如需更多信息,请参阅 CXF 文档的 Code first development 部分。
5.1.8.4. 从 WSDL 生成模型类 复制链接链接已复制到粘贴板!
在 Quarkus 代码生成阶段,quarkus-cxf 扩展支持从 WSDL 生成 Java 类。
本节中显示的代码片段来自 Quarkus CXF 的源树中的客户端 集成测试。您可能需要将其作为可执行示例进行检查。
您需要设置几个内容才能使 CXF 代码生成正常工作:
-
在项目中具有
io.quarkiverse.cxf:quarkus-cxf依赖项 对于 Maven 项目,
generate-code目标需要在quarkus-maven-plugin配置中存在:pom.xml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
对于 Gradle 项目,不需要额外的
io.quarkus插件配置 -
将您的 WSDL 文件置于
src/main/resources或src/test/resources或其中的任何子目录下。 -
您的 WSDL 文件名必须以
.wsdl结尾 将
quarkus.cxf.codegen.wsdl2java.includes配置属性设置为 与您要处理的 WSDL 文件匹配的模式。如果要处理src/main/resources/wsdl或src/test/resources/wsdl下的所有 WSDL 文件,请按如下所示设置:application.properties
quarkus.cxf.codegen.wsdl2java.includes = wsdl/*.wsdl
quarkus.cxf.codegen.wsdl2java.includes = wsdl/*.wsdlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
这将在 target/generated-sources/wsdl2java 或 target/generated-test-sources/wsdl2java 目录中生成 Java 类。它们由编译器插件自动选择。因此,我们可以自由地引用应用程序或测试代码。
请注意,quarkus-cxf 代码生成使用来自 CXF 的 wsdl2Java 工具(位于 hood 下)。wsdl2Java 通过包含和排除选择的每个 WSDL 文件单独调用。
通过 quarkus.cxf.codegen. 配置参数可以将自定义参数传递给 wsdl2java。
wsdl2java.additional-params
如果需要为每个 WSDL 文件使用不同的 additional-params,您可能需要为它们分别定义一个单独的命名参数。下面是一个示例:
application.properties
将 io.quarkiverse.cxf:quarkus-cxf-xjc-plugins 依赖项添加到项目,以便可以使用 -xjc-Xbg,-xjc-Xdv,-xjc-Xjavadoc,-xjc-Xproperty-listener,-xjc-Xts 和 -xjc-Xwsdlextension wsdl2java.
5.1.8.4.1. 非 ASCII Characters 复制链接链接已复制到粘贴板!
有时,由于代码中包含非 ASCII 字符,因此 wsdl2java 自动生成的 Java 类可能无法与 GraalVM 完全兼容。在原生镜像构建过程中可能会出现与以下类似的例外:
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] compile: 161 459,15 ms, 8,54 GB
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] image: 158 272,73 ms, 8,43 GB
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] write: 205,82 ms, 8,43 GB
Fatal error:com.oracle.svm.core.util.VMError$HostedError: java.lang.RuntimeException: oops : expected ASCII string! com.oracle.svm.reflect.OperationOrderStatusType_CRÉÉ_f151156b0d42ecdbdfb919501d8a86dda8733012_1456.hashCode
at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:72)
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] compile: 161 459,15 ms, 8,54 GB
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] image: 158 272,73 ms, 8,43 GB
[quarkus-dalkia-ticket-loader-1.0.0-SNAPSHOT-runner:26] write: 205,82 ms, 8,43 GB
Fatal error:com.oracle.svm.core.util.VMError$HostedError: java.lang.RuntimeException: oops : expected ASCII string! com.oracle.svm.reflect.OperationOrderStatusType_CRÉÉ_f151156b0d42ecdbdfb919501d8a86dda8733012_1456.hashCode
at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:72)
以下是 Java 类中自动生成的非 ASCII 字符示例:
以 \u 开头的任何内容都将是一个问题。因此,需要以下重构:
5.1.8.5. 从 Java 生成 WSDL 文档 复制链接链接已复制到粘贴板!
如果您的服务位于 http://your-host/your-service?wsdl 的 WSDL 服务不足,因为您想要将其分发为 Maven 构件,那么您可以在构建时使用 java2ws 生成 WSDL 文档。
您不需要直接调用 CXF 提供的 java2ws 工具,您不必使用 cxf-java2ws-plugin。
quarkus-cxf wraps java2ws,您可以在 application.properties 中配置它作为应用程序的任何其他方面。
下面是一个示例:
本节中使用的代码片段示例来自 Quarkus CXF 源树中的服务器 集成测试
application.properties
quarkus.cxf.java2ws.includes = io.quarkiverse.cxf.it.server.HelloServiceImpl,io.quarkiverse.cxf.it.server.FaultyHelloServiceImpl quarkus.cxf.java2ws.wsdl-name-template = %TARGET_DIR%/Java2wsTest/%SIMPLE_CLASS_NAME%-from-java2ws.wsdl
quarkus.cxf.java2ws.includes = io.quarkiverse.cxf.it.server.HelloServiceImpl,io.quarkiverse.cxf.it.server.FaultyHelloServiceImpl
quarkus.cxf.java2ws.wsdl-name-template = %TARGET_DIR%/Java2wsTest/%SIMPLE_CLASS_NAME%-from-java2ws.wsdl
在这里,我们已指示 java2ws 为两个服务类生成 WSDLs,即 HelloServiceImpl 和 FaultyHelloServiceImpl。
服务类必须使用 jakarta.xml.ws.WebService 注解,以进行 java2ws 处理。
这两个生成的 WSDL 文档将分别存储为 target/Java2wsTest/FaultyHelloServiceImpl-from-java2ws.wsdl 和 target/Java2wsTest/HelloServiceImpl-from-java2ws.wsdl。
与在 Quarkus 源生成阶段执行的 wsdl2java 不同,java2ws 是编译后发生的 Quarkus 扩展的一部分。java2ws 的输入是,所有 Java 类文件之后。因此,您不需要将 generate-code 添加到 java2ws 的 quarkus-maven-plugin 中。
5.1.8.5.1. 另请参阅 复制链接链接已复制到粘贴板!
-
quarkus.cxf.java2wsurl 配置属性quarkus-cxf
5.1.9. CXF Interceptors 和 features, JAX-WS Handlers 复制链接链接已复制到粘贴板!
查看以下章节以了解定制 SOAP 请求和响应处理的各种方法:
5.1.9.1. CXF Interceptors 和功能 复制链接链接已复制到粘贴板!
CXF 拦截器 和 CXF 功能 可以使用注解或 application.properties 配置添加到您的客户端或服务器。
虽然 CXF 提供了多个开箱即用的嵌入式拦截器和功能,但您也可以集成自定义开发的实现。
注解可用于服务接口或实施类。
您还可以在 application.properties 文件中定义配置。
quarkus.cxf.endpoint."/greeting-service".features=org.apache.cxf.ext.logging.LoggingFeature quarkus.cxf.endpoint."/greeting-service".in-interceptors=org.acme.Test1Interceptor quarkus.cxf.endpoint."/greeting-service".out-interceptors=org.acme.Test1Interceptor quarkus.cxf.endpoint."/greeting-service".in-fault-interceptors=org.acme.Test2Interceptor,org.acme.Test3Intercetpor quarkus.cxf.endpoint."/greeting-service".out-fault-interceptors=org.acme.Test1Intercetpor
quarkus.cxf.endpoint."/greeting-service".features=org.apache.cxf.ext.logging.LoggingFeature
quarkus.cxf.endpoint."/greeting-service".in-interceptors=org.acme.Test1Interceptor
quarkus.cxf.endpoint."/greeting-service".out-interceptors=org.acme.Test1Interceptor
quarkus.cxf.endpoint."/greeting-service".in-fault-interceptors=org.acme.Test2Interceptor,org.acme.Test3Intercetpor
quarkus.cxf.endpoint."/greeting-service".out-fault-interceptors=org.acme.Test1Intercetpor
功能和拦截器类都会首先通过 CDI 加载。它们可以通过完全限定类名称或 bean 名称来引用。
如果没有 CDI Bean 可用,则会调用没有参数的构造器来实例化每个类。
5.1.9.2. JAX-WS 处理程序 复制链接链接已复制到粘贴板!
作为 @HandlerChain 注释的替代选择,JAX-WS 处理程序 可以通过 application.properties 添加至您的客户端或服务器:
application.properties
# A web service endpoint with multiple Handler classes quarkus.cxf.endpoint."/greeting-service".handlers=org.acme.MySOAPHandler,org.acme.AnotherSOAPHandler # A web service client with a single Handler quarkus.cxf.client."greeting-client".handlers=org.acme.MySOAPHandler
# A web service endpoint with multiple Handler classes
quarkus.cxf.endpoint."/greeting-service".handlers=org.acme.MySOAPHandler,org.acme.AnotherSOAPHandler
# A web service client with a single Handler
quarkus.cxf.client."greeting-client".handlers=org.acme.MySOAPHandler
其中 MySOAPHandler 可能类似如下:
SOAPHandler 类首先通过 CDI 加载。
如果没有 CDI Bean 可用,则会调用没有参数的构造器来实例化每个类。
5.1.10. 高级服务主题 复制链接链接已复制到粘贴板!
有关实现 SOAP 服务端点的更多详细信息,请查看以下章节:
5.1.10.1. 服务端点和路径 复制链接链接已复制到粘贴板!
让我们来说明如何在特定 URL 路径下公开服务端点。
5.1.10.1.1. 通过 application.properties设置端点路径 复制链接链接已复制到粘贴板!
在 First SOAP Web 服务 章节中,我们解释了如何使用 application.properties 来公开服务:
application.properties
有了此设置,可以在 http://localhost:8080/soap/hello 下访问 io.quarkiverse.cxf.it.server.HelloServiceImpl。
这是自 Quarkus CXF 非常开始工作的传统方法。
5.1.10.1.2. 使用 @CXFEndpoint 注释设置端点路径 复制链接链接已复制到粘贴板!
自 Quarkus CXF 3.11.0 起,有新的方法在特定路径下公开端点 :@io.quarkiverse.cxf.annotation.CXFEndpoint 注解。该路径通过其非可选 属性值 进行设置,它相对于 quarkus.cxf.path,就像通过 application.properties 执行时一样。
让我们来看一个示例。
本节中显示的代码片段示例来自 Quarkus CXF 的源树中的客户端和服务器 集成测试。您可能需要将其用作可运行的示例。
PathAnnotationHelloServiceImpl.java
- 1
- 如果
application.properties中的quarkus.cxf.path的值为/soap,则该服务可在http://localhost:8080/soap/path-annotation下访问。
MyServiceImpl 类型的 @CxfEndpoint ("/my-path") 注释等同于 application.properties 中的 quarkus.cxf.endpoint."/my-path".implementor = org.acme.MyServiceImpl 行。因此,仅使用其中之一就足够了。
在 /my-path 端点的 application.properties 中设置的其他选项,将只与 @CXFEndpoint ("/my-path") 合并。
5.1.10.1.2.1. 在生成者方法上使用 @CXFEndpoint 注释 复制链接链接已复制到粘贴板!
@CXFEndpoint 注释也可用于生成者方法。这特别适用于测试客户端,因为返回的实现可以是模拟的。
下面是一个示例:
MockedEndpointTest.java
- 1
- 在这里,我们对返回
HelloService接口的模拟的方法使用@CXFEndpoint注释。不需要@jakarta.enterprise.inject.Produces注解,因为 Quarkus CXF 声明@CXFEndpoint作为定义注解的 bean。 - 2
- 客户端在
application.properties中配置以连接到http://localhost:8080/soap/helloMock - 3
- 断言可确保服务实施可以按预期工作。
5.1.10.2. JAX-WS 提供商 复制链接链接已复制到粘贴板!
JAX-WS 提供程序 受到全面支持,可以按照如下所示实施。
根据以下示例 供应商 实现:
application.properties 可以配置如下。
# A web service endpoint with the Provider implementation class quarkus.cxf.endpoint."/stream-source".implementor=org.acme.StreamSourcePayloadProvider
# A web service endpoint with the Provider implementation class
quarkus.cxf.endpoint."/stream-source".implementor=org.acme.StreamSourcePayloadProvider
供应商 类首先通过 CDI 加载。
如果没有 CDI Bean 可用,则会调用没有参数的构造器来实例化每个类。
5.1.10.3. REST 和 SOAP 端点 复制链接链接已复制到粘贴板!
有时,使用 Quarkus CXF 扩展的同一项目中可能需要 REST 端点。REST 端点路径必须与 SOAP 端点路径不同(为了避免在两个协议之间请求转发冲突)。
例如,如果在 WSDL 中声明了 WeatherWebService 接口,您可以先创建 org.acme.cxf.WeatherWebServiceImpl 类,如下所示:
之后,您需要为 CXF Web 服务指定根上下文,如 配置文档 中所示,以根据其根上下文路径分割 REST (例如 RESTEasy)和 SOAP 路由。
CXF 的 SOAP 属性:
quarkus.cxf.path=/soap quarkus.cxf.endpoint."/weather".implementor=org.acme.cxf.WeatherWebServiceImpl
quarkus.cxf.path=/soap
quarkus.cxf.endpoint."/weather".implementor=org.acme.cxf.WeatherWebServiceImpl
现在,请想象以下 RESTEasy 端点:
您可以通过配置 REASTEasy 路径来分隔 REST 端点:
quarkus.resteasy.path=/rest
quarkus.resteasy.path=/rest
现在,您应该能够向在单个项目中部署的 REST 和 SOAP 端点发送请求,该端点位于:
- http://localhost:8080/rest/healthcheck for REST
- http://localhost:8080/soap/weather 用于 SOAP
5.1.10.4. 在反向代理后运行 复制链接链接已复制到粘贴板!
SOAP 请求旨在向 Quarkus 上运行的服务进行路由,该代理可以生成额外标头(如 X-Forwarded-Host),以保留来自面向客户端的代理服务器的信息,并在涉及时更改或丢失。在这些情况下,可将 Quarkus 配置为自动更新协议、主机、端口和 URI 等信息,反映这些标头中的值。
如需更多详细信息,请参阅 Quarkus HTTP 参考。
对各种 X-Forwarded 标头的 quarkus CXF 支持可以在 Quarkus 配置中正常工作。
激活此功能会使服务器暴露几个安全问题(例如,信息欺骗)。只有在反向代理后运行时,请考虑将其激活。
以下是相关的 Quarkus 属性及其对 Quarkus CXF 的影响:
quarkus.http.proxy.proxy-address-forwarding- 主开关来启用请求目的地部分的重写。- 如果启用,在整个 CXF 服务器堆栈中,请求字段的重写将有效。
-
如果启用,则使用通过
X-Forwarded-Proto和X-Forwarded-Port标头传递的值来设置协议部分,以及jakarta.servlet.http.HttpServletRequest.getRequestURL ()返回的 URL 的端口部分。 -
如果启用,通过
X-Forwarded-For传递的值将由jakarta.servlet.ServletRequest.getRemoteAddr ()返回。
-
quarkus.http.proxy.enable-forwarded-host- 启用jakarta.servlet.http.HttpServletRequest.getRequestURL ()返回的 URL 部分的重写。实际主机名从通过quarkus.http.proxy.forwarded-host-header配置的标头获取(默认为X-Forwarded-Host)。 -
quarkus.http.proxy.enable-forwarded-prefix- 启用jakarta.servlet.http.HttpServletRequest.getRequestURL ()返回的 URL 的路径部分的重写,以及jakarta.servlet.http.HttpServletRequest.getRequestURI ()返回的 URI 部分。实际路径前缀从通过quarkus.http.proxy.forwarded-prefix-header配置的标头获取(默认为X-Forwarded-Prefix)。
以下是复制到 application.properties 的最常见片段:
quarkus.http.proxy.proxy-address-forwarding = true quarkus.http.proxy.enable-forwarded-host = true quarkus.http.proxy.enable-forwarded-prefix = true
quarkus.http.proxy.proxy-address-forwarding = true
quarkus.http.proxy.enable-forwarded-host = true
quarkus.http.proxy.enable-forwarded-prefix = true
这些设置的可观察影响之一是更改在 http://localhost:8080/services/my-service?wsdl 上提供的 WSDL 中的位置值。例如,如果请求包含以下标头
X-Forwarded-Proto: https X-Forwarded-Host: api.example.com X-Forwarded-Port: 443 X-Forwarded-Prefix: /my-prefix
X-Forwarded-Proto: https
X-Forwarded-Host: api.example.com
X-Forwarded-Port: 443
X-Forwarded-Prefix: /my-prefix
然后 http://localhost:8080/services/my-service?wsdl 上提供的 WSDL 将包含 以下位置 :
... <soap:address location="https://api.example.com:443/my-prefix/services/my-service"/> ...
...
<soap:address location="https://api.example.com:443/my-prefix/services/my-service"/>
...
5.1.11. 高级 SOAP 客户端主题 复制链接链接已复制到粘贴板!
有关实现 SOAP 客户端的更多详细信息,请查看以下章节:
5.1.11.1. client-endpoint-url 默认值 复制链接链接已复制到粘贴板!
如果省略 application.properties 中的 client-endpoint-url 属性,则 CXF Quarkus 扩展将假定该服务在 http://localhost:8080/{service-path} 中发布,其中 {service-path} 派生自
-
配置属性
quarkus.cxf.path(如果指定); 和 - SEI 的类名称(小写)
给定 quarkus.cxf.path = /ws,CalculatorService 的默认有效 client-endpoint-url 为 http://localhost:8080/ws/org.jboss.eap.quickstarts.wscalculator.calculator.calculatorservice。
如果没有指定 quarkus.cxf.path,client-endpoint-url 将只是 http://localhost:8080/org.jboss.eap.quickstarts.wscalculator.calculator.calculatorservice。
5.1.11.2. 配置多个客户端 复制链接链接已复制到粘贴板!
在上例中,我们只配置了一个名为 myCalculator 的单个客户端。当然,您可以使用多个标识符配置指向不同 URL 和/或实施不同 SEI 的多个客户端:
application.properties
5.1.11.3. 通过 @CXFClient注入的客户端的 CDI 范围 复制链接链接已复制到粘贴板!
quarkus CXF 在默认的 @Dependent 范围中生成通过 @io.quarkiverse.cxf.annotation.CXFClient 注入的所有客户端。因此,注入的实例的实际范围取决于注入客户端的 bean 的 CDI 范围。
因此,如果客户端注入 @ApplicationScoped bean,则客户端实例也会变为 @ApplicationScoped。如果客户端注入 @RequestScoped bean,则客户端实例也会变为 @RequestScoped。
如果您需要在应用程序启动后 动态配置客户端,则此行为会变得方便。
5.1.11.4. 启动时编程客户端配置 复制链接链接已复制到粘贴板!
要在应用程序启动时配置所有客户端,您可以实施 HTTPConduitConfigurer,并使用 StartupEvent observer 方法在 CXF 总线上设置它。
在以下示例中,我们配置 HTTPClientPolicy 的一些方面。可以利用同样的方法来自定义授权策略 ,Proxy ,甚至您的客户端的 AuthorizationPolicy TLSClientParameters。
5.1.11.5. 动态客户端配置 复制链接链接已复制到粘贴板!
有时,您需要在应用 启动后重新配置客户端,甚至在 每个请求之前重新配置客户端。例如,这可能是每个请求发送到不同的远程 URL 的情况。
CXF 提供了一个 API,用于设置远程端点的 URL。但是,在可能从其他线程访问的客户端实例上使用该 API 可能会导致竞争条件。
5.1.11.5.1. 防止对 CXF 客户端的并发访问 复制链接链接已复制到粘贴板!
如果您的客户端用作外部请求的一部分,您可以将客户端注入到 @RequestScoped bean 中。然后,每个请求都由一个全新的客户端实例提供,您可以安全地进行配置。
例如,如果您的客户端从 REST-handler 方法调用,或从提供外部请求的 @WebMethod 调用时,此解决方案适用。
5.1.11.6. 纯客户端应用程序 复制链接链接已复制到粘贴板!
Quarkus batch (如定期调度)或命令行应用程序,在没有 HTTP 服务器的情况下可以这样做。使用以下属性以防止在启动时启动 HTTP 服务器:
quarkus.http.host-enabled = false
quarkus.http.host-enabled = false
5.1.11.7. 防止资源泄漏 复制链接链接已复制到粘贴板!
CXF 客户端代理实现 java.io.Closeable。因此,在客户端不再需要释放所有关联的系统资源 (如线程)后,调用(关闭) proxy)。close () 非常重要。
quarkus CXF 在被 CDI 容器处理后立即自动关闭通过 @io.quarkiverse.cxf.annotation.CXFClient 注入的客户端。
对于手动创建的客户端代理,您需要调用 (关闭) proxy).close () :
5.1.12. Camel Integration 复制链接链接已复制到粘贴板!
Camel Quarkus 支持 CXF 版本 2.12.0。在 hood 下,实施基于 Quarkus CXF。因此,Camel Quarkus 也提供 Quarkus CXF 中的所有功能。
详情请参考 Camel Quarkus CXF SOAP 扩展文档。
5.1.13. 例子 复制链接链接已复制到粘贴板!
代码库的 integration-tests 文件夹 提供了各种示例,演示了如何广泛使用此扩展。