当 pom.xml 中缺少 cxf-rt-transports-http 时,将生成的 CXF 客户端 jar 与 Spring 集成引导失败

integrating generated CXF client jar with Spring Boot fails when cxf-rt-transports-http is missing in pom.xml

我想将 Spring 应用程序迁移到 Spring Boot。原始应用程序由几个 Maven 模块组成,我想重用现有模块之一。我要重用的模块是生成的 cxf web 服务客户端。它在应用程序的 pom.xml 中链接如下:

<dependency>
   <groupId>generated.package</groupId>
   <artifactId>cxf-service-adapter</artifactId>
   <version>1.0</version>           
</dependency>

该模块中生成的 GenCxfService 界面如下所示

@WebService(targetNamespace = "https://the-domain/the-service/", name = "genCxfService")
@XmlSeeAlso({ObjectFactory.class})
public interface GenCxfService {
    // the anotated web service methods
    // ....
}

我需要 Web 服务客户端接口 GenCxfService 由 Spring Boot 管理,以便我可以将其传递到 spring 安全性 AuthenticationProvider


嗯,我认为这没什么大不了的。我从模块中取出已编译的 cxf-service-adapter-1.0.jar,将其放入自己的项目内存储库中,并尝试将 java 配置设置为 @autowire bean。首先我是这样尝试的:

import generated.package.GenCxfService;
...
@ComponentScan({"generated.package.*","my.package.*"})
...
@Bean
public MyAuthenticationProvider myAuthenticationProvider() {
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setAddress("https://the-domain/the-service/");
    factory.setServiceClass(GenCxfService.class);
    GenCxfService genCxfService = (GenCxfService) factory.create();
    return new my.package.authentication.MyAuthenticationProvider(userDAO, genCxfService);
}

这在运行时给了我以下异常:

javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: https://the-domain/the-service/the-wsdl.asmx and transport: http://schemas.xmlsoap.org/soap/http
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
    at com.sun.proxy.$Proxy126.validateMyUser(Unknown Source)
    at my.package.authentication.MyAuthenticationProvider.authenticate(MyAuthenticationProvider.java:47)

我以为我只是有一个错误的 java 配置,并尝试通过重用原始项目模块中现有的 xml 配置来解决问题,使用

@ImportResource({"classpath:web-service.xml"})

与 xml 文件:

    <jaxws:client id="genCxfService"
        serviceClass="generated.package.GenCxfService"
        address="https://the-domain/the-service/the-wsdl.asmx">
    </jaxws:client>

    <bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />

    <cxf:bus>
        <cxf:inInterceptors>
            <ref bean="logInbound" />
        </cxf:inInterceptors>
        <cxf:inFaultInterceptors>
            <ref bean="logInbound" />
        </cxf:inFaultInterceptors>
    </cxf:bus>

这是 cxf documentation (Configuring a Spring Client Option 1) 中客户端的配置方式。尽管如此,我仍然得到同样的错误。

我做错了什么?

更新

cxf-rt-transports-http 添加到 pom 中成功了:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
</dependency>

谁能解释为什么缺少库不会在启动期间抛出异常,而是在运行时抛出异常?

提前致谢。

Spring boot 会在运行时找到 类 所以你不必依赖特定的库,它会使用反射来查找 类 满足它需要允许轻松交换实现的接口。

类 也是延迟启动或查找的,这就是为什么只有在发送请求时才会发生这种情况,而不是在请求开始时发生。