前言https://blog.csdn.net/dbeautifulLife/article/details/78326662

前面我们已经整合spring-ws实现了web service的服务端:Spring Boot整合spring-ws开发web service

接下来就是实现客户端进行调用了。

添加依赖

客户端,同样的需要先添加依赖:

  1. <dependency>

  2.    <groupId>org.springframework.boot</groupId>

  3.    <artifactId>spring-boot-starter-ws</artifactId>

  4. </dependency>

  5. <dependency>

  6.    <groupId>wsdl4j</groupId>

  7.    <artifactId>wsdl4j</artifactId>

  8. </dependency>

获取wsdl文件

服务端由一个xsd文件开始,客户端则是由一个wsdl文件开始。

获取wsdl文件也十分简单,用浏览器访问web service地址,然后另存为即可。当然也可以直接用url地址来生成代码,只不过我习惯本地另存为后再生成。

完整的wsdl文件内容如下:

  1. <wsdl:definitions

  2.    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

  3.    xmlns:sch="http://www.dexcoder.com/ws"

  4.    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

  5.    xmlns:tns="http://www.dexcoder.com/ws" targetNamespace="http://www.dexcoder.com/ws">

  6.    <wsdl:types>

  7.        <xs:schema

  8.            xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.dexcoder.com/ws">

  9.            <xs:element name="getCountryRequest">

  10.                <xs:complexType>

  11.                    <xs:sequence>

  12.                        <xs:element name="name" type="xs:string"/>

  13.                    </xs:sequence>

  14.                </xs:complexType>

  15.            </xs:element>

  16.            <xs:element name="getCountryResponse">

  17.                <xs:complexType>

  18.                    <xs:sequence>

  19.                        <xs:element name="country" type="tns:country"/>

  20.                    </xs:sequence>

  21.                </xs:complexType>

  22.            </xs:element>

  23.            <xs:complexType name="country">

  24.                <xs:sequence>

  25.                    <xs:element name="name" type="xs:string"/>

  26.                    <xs:element name="population" type="xs:int"/>

  27.                    <xs:element name="capital" type="xs:string"/>

  28.                    <xs:element name="currency" type="tns:currency"/>

  29.                </xs:sequence>

  30.            </xs:complexType>

  31.            <xs:simpleType name="currency">

  32.                <xs:restriction base="xs:string">

  33.                    <xs:enumeration value="GBP"/>

  34.                    <xs:enumeration value="EUR"/>

  35.                    <xs:enumeration value="PLN"/>

  36.                </xs:restriction>

  37.            </xs:simpleType>

  38.        </xs:schema>

  39.    </wsdl:types>

  40.    <wsdl:message name="getCountryResponse">

  41.        <wsdl:part element="tns:getCountryResponse" name="getCountryResponse"></wsdl:part>

  42.    </wsdl:message>

  43.    <wsdl:message name="getCountryRequest">

  44.        <wsdl:part element="tns:getCountryRequest" name="getCountryRequest"></wsdl:part>

  45.    </wsdl:message>

  46.    <wsdl:portType name="CountriesPort">

  47.        <wsdl:operation name="getCountry">

  48.            <wsdl:input message="tns:getCountryRequest" name="getCountryRequest"></wsdl:input>

  49.            <wsdl:output message="tns:getCountryResponse" name="getCountryResponse"></wsdl:output>

  50.        </wsdl:operation>

  51.    </wsdl:portType>

  52.    <wsdl:binding name="CountriesPortSoap11" type="tns:CountriesPort">

  53.        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

  54.        <wsdl:operation name="getCountry">

  55.            <soap:operation soapAction=""/>

  56.            <wsdl:input name="getCountryRequest">

  57.                <soap:body use="literal"/>

  58.            </wsdl:input>

  59.            <wsdl:output name="getCountryResponse">

  60.                <soap:body use="literal"/>

  61.            </wsdl:output>

  62.        </wsdl:operation>

  63.    </wsdl:binding>

  64.    <wsdl:service name="CountriesPortService">

  65.        <wsdl:port binding="tns:CountriesPortSoap11" name="CountriesPortSoap11">

  66.            <soap:address/>

  67.        </wsdl:port>

  68.    </wsdl:service>

  69. </wsdl:definitions>

添加maven的jaxb2插件生成代码

跟服务端根据xsd来生成代码类似,客户端同样可以根据wsdl来生成代码。maven插件依赖:

  1. <plugin>

  2.    <groupId>org.jvnet.jaxb2.maven2</groupId>

  3.    <artifactId>maven-jaxb2-plugin</artifactId>

  4.    <version>0.12.3</version>

  5.    <executions>

  6.        <execution>

  7.            <goals>

  8.                <goal>generate</goal>

  9.            </goals>

  10.        </execution>

  11.    </executions>

  12.    <configuration>

  13.        <schemaLanguage>WSDL</schemaLanguage>

  14.        <generatePackage>com.dexcoder.ws</generatePackage>

  15.        <generateDirectory>${basedir}/src/main/java</generateDirectory>

  16.        <schemas>

  17.            <schema>

  18.                <fileset>

  19.                    <!-- Defaults to schemaDirectory. -->

  20.                    <directory>${basedir}/src/main/resources/schemas</directory>

  21.                    <!-- Defaults to schemaIncludes. -->

  22.                    <includes>

  23.                        <include>*.wsdl</include>

  24.                    </includes>

  25.                    <!-- Defaults to schemaIncludes -->

  26.                    <!--<excludes>-->

  27.                    <!--<exclude>*.xs</exclude>-->

  28.                    <!--</excludes>-->

  29.                </fileset>

  30.                <!--<url>http://localhost:8080/ws/countries.wsdl</url>-->

  31.            </schema>

  32.        </schemas>

  33.    </configuration>

  34. </plugin>

同样mvn install之后将生成客户端代码。这里生成的代码跟我们前面发布的服务端代码应该是一样的,当然包名可能不同这个由你指定。

在生成代码的同时会生成META-INF文件夹,这个可以移到resources目录下或者直接删除都没有关系。生成后的项目结构图:

项目结构

编写ws客户端

生成了代码之后,编写客户端变的很容易,具体代码如下:

  1. public class WsClient extends WebServiceGatewaySupport {


  2.    public GetCountryResponse getCountry(String name) {


  3.        GetCountryRequest request = new GetCountryRequest();

  4.        request.setName(name);


  5.        GetCountryResponse response = (GetCountryResponse) getWebServiceTemplate().marshalSendAndReceive(

  6.            "http://localhost:8080/ws/countries.wsdl", request);


  7.        return response;

  8.    }

  9. }

配置ws客户端

编写完一切代码之后,同样需要配置到spring boot才行,ContextPath指定刚才生成代码所在的包名,它会到该包下去寻找相应的类自动进行数据转换:

  1. @Configuration

  2. public class WSConfig {


  3.    @Bean

  4.    public Jaxb2Marshaller marshaller() {

  5.        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

  6.        marshaller.setContextPath("com.dexcoder.ws");

  7.        return marshaller;

  8.    }


  9.    @Bean

  10.    public WsClient wsClient(Jaxb2Marshaller marshaller) {

  11.        WsClient client = new WsClient();

  12.        client.setDefaultUri("http://localhost:8080/ws/countries.wsdl");

  13.        client.setMarshaller(marshaller);

  14.        client.setUnmarshaller(marshaller);

  15.        return client;

  16.    }

  17. }

运行

到这里所有的调用代码都已经完成了,剩下的就是运行来检测是否调用成功。

这里我们来编写一个Controller来简单测试一下。

  1. @RestController

  2. public class IndexController {


  3.    @Autowired

  4.    private WsClient wsClient;


  5.    @RequestMapping("callws")

  6.    public Object callWs() {

  7.        GetCountryResponse response = wsClient.getCountry("hello");

  8.        return response.getCountry();

  9.    }

  10. }

使用了RestController,直接将调用ws返回的数据用json格式输出到页面。

启动spring boot,访问http://localhost:8081/callws 这里把端口换成了8081,因为默认的8080已经被前面的服务端占用了。

可以看到成功调用了ws的服务端并返回了数据,hello部分为我们发送过去的参数:

ws客户端返回数据