在Spring中调用SOAP Web服务

2023/05/12

1. 概述

之前,我们了解了如何使用Spring创建SOAP Web服务

在本教程中,我们将学习如何创建基于Spring的客户端来使用此Web服务

Java中调用SOAP Web服务时,我们使用JAX-WS RI做了同样的事情。

2. Spring SOAP Web服务-快速回顾

早些时候,我们在Spring中创建了一个Web服务来获取一个国家的数据,给定它的名字。在深入研究客户端实现之前,让我们快速回顾一下我们是如何做到这一点的。

按照契约优先的方法,我们首先编写了一个定义域的XML模式文件。然后,我们使用此XSD通过jaxb2-maven-plugin为请求、响应和数据模型生成类。

之后我们编写了四个类:

最后,我们通过cURL发送SOAP请求对其进行了测试。

现在让我们通过运行上面的Boot应用程序来启动服务器,然后继续下一步。

3. 客户端

在这里,我们将构建一个Spring客户端来调用和测试上述Web服务

现在,让我们逐步地看看我们需要做什么来创建一个客户端。

3.1 生成客户端代码

首先,我们将使用http://localhost:8080/ws/countries.wsdl提供的WSDL生成一些类。我们将下载并将其保存在我们的src/main/resources文件夹中。

要使用Maven生成代码,我们将maven-jaxb2-plugin添加到我们的pom.xml中

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemaLanguage>WSDL</schemaLanguage>
        <generateDirectory>${project.basedir}/src/main/java</generateDirectory>
        <generatePackage>cn.tuyucheng.taketoday.springsoap.client.gen</generatePackage>
        <schemaDirectory>${project.basedir}/src/main/resources</schemaDirectory>
        <schemaIncludes>
            <include>countries.wsdl</include>
        </schemaIncludes>
    </configuration>
</plugin>

值得注意的是,在我们定义的插件配置中:

  • generateDirectory:将保存生成的工件的文件夹
  • generatePackage:工件将使用的包名称
  • schemaDirectory和schemaIncludes:WSDL的目录和文件名

为了执行JAXB生成过程,我们将通过简单地构建项目来执行此插件:

mvn compile

有趣的是,此处生成的工件与为服务生成的工件相同

让我们列出我们将要使用的那些:

  • Country.java和Currency.java:代表数据模型的POJO
  • GetCountryRequest.java:请求类型
  • GetCountryResponse.java:响应类型

该服务可以部署在世界任何地方,并且仅使用它的WSDL,我们就能够在客户端生成与服务器相同的类!

3.2 CountryClient

接下来,我们需要扩展Spring的WebServiceGatewaySupport以与Web服务进行交互。

我们称这个类为CountryClient:

public class CountryClient extends WebServiceGatewaySupport {

    public GetCountryResponse getCountry(String country) {
        GetCountryRequest request = new GetCountryRequest();
        request.setName(country);

        GetCountryResponse response = (GetCountryResponse) getWebServiceTemplate()
              .marshalSendAndReceive(request);
        return response;
    }
}

在这里,我们定义了单个方法getCountry,对应于Web服务公开的操作。在该方法中,我们创建了一个GetCountryRequest实例并调用Web服务来获取GetCountryResponse。换句话说,这里是我们执行SOAP交换的地方

正如我们所见,Spring通过其WebServiceTemplate使调用变得非常简单。我们使用模板的方法marshalSendAndReceive来执行SOAP交换。

XML转换在这里通过插入式Marshaller处理。

现在让我们看看这个Marshaller来自哪里的配置。

3.3 CountryClientConfig

我们需要配置我们的Spring WS客户端的是两个bean。

首先,一个Jaxb2Marshaller将消息与XML相互转换,其次是我们的CountryClient,它将注入marshaller bean:

@Configuration
public class CountryClientConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("cn.tuyucheng.taketoday.springsoap.client.gen");
        return marshaller;
    }
    @Bean
    public CountryClient countryClient(Jaxb2Marshaller marshaller) {
        CountryClient client = new CountryClient();
        client.setDefaultUri("http://localhost:8080/ws");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }
}

在这里,我们需要注意编组器的上下文路径与pom.xml的插件配置中指定的generatePackage相同。

另请注意此处客户端的默认URI。它被设置为WSDL中指定的soap:address位置。

4. 测试客户端

接下来,我们将编写一个JUnit测试来验证我们的客户端是否按预期运行:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CountryClientConfig.class, loader = AnnotationConfigContextLoader.class)
public class ClientLiveTest {

    @Autowired
    CountryClient client;

    @Test
    public void givenCountryService_whenCountryPoland_thenCapitalIsWarsaw() {
        GetCountryResponse response = client.getCountry("Poland");
        assertEquals("Warsaw", response.getCountry().getCapital());
    }

    @Test
    public void givenCountryService_whenCountrySpain_thenCurrencyEUR() {
        GetCountryResponse response = client.getCountry("Spain");
        assertEquals(Currency.EUR, response.getCountry().getCurrency());
    }
}

正如我们所看到的,我们注入了CountryClientConfig中定义的CountryClient bean。然后,我们使用它的getCountry调用远程服务,如前所述。

此外,我们能够使用生成的数据模型POJOs、Country和Currency提取断言所需的信息。

5. 总结

在本教程中,我们了解了如何使用Spring WS调用SOAP Web服务的基础知识。

我们只是触及了Spring在SOAP Web服务领域所提供的内容的皮毛;有很多值得探索的地方。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章