Compare commits
8 Commits
2.0.2.RELE
...
2.0.8.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51ffb90821 | ||
|
|
8c6e8bee12 | ||
|
|
ab5e8adfc2 | ||
|
|
4002ac9801 | ||
|
|
160ffd1480 | ||
|
|
7fa41df3ff | ||
|
|
f5ee891b92 | ||
|
|
114cdf9303 |
52
README.adoc
52
README.adoc
@@ -2,7 +2,7 @@
|
||||
:toc:
|
||||
:project_id: gs-consuming-web-service
|
||||
:spring_version: current
|
||||
:spring_boot_version: 2.0.2.RELEASE
|
||||
:spring_boot_version: 2.0.8.RELEASE
|
||||
:icons: font
|
||||
:source-highlighter: prettify
|
||||
|
||||
@@ -10,10 +10,10 @@ This guide walks you through the process of consuming a link:/understanding/SOAP
|
||||
|
||||
== What you'll build
|
||||
|
||||
You will build a client that fetches stock market quotes data from a remote, WSDL-based web service using http://en.wikipedia.org/wiki/SOAP[SOAP].
|
||||
You can find out more about the quote service at http://www.webservicex.com/stockquote.asmx?op=GetQuote.
|
||||
You will build a client that fetches country data data from a remote, WSDL-based web service using http://en.wikipedia.org/wiki/SOAP[SOAP].
|
||||
You can find out more about the country service, and run the service yourself by following https://spring.io/guides/gs/producing-web-service/[this guide].
|
||||
|
||||
The service provides stock market quotes. You will be able to use your own ticker symbol.
|
||||
The service provides country data. You will be able to query data about a country based on its name.
|
||||
|
||||
|
||||
== What you'll need
|
||||
@@ -35,12 +35,15 @@ include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/
|
||||
NOTE: If you read link:/guides/gs/producing-web-service[Producing a SOAP web service], you might be wondering why this guide doesn't use *spring-boot-starter-ws*? That Spring Boot starter is
|
||||
only for server-side web services. That starter brings on board things like embedded Tomcat, which isn't need to make a web call.
|
||||
|
||||
== Run the target web service locally
|
||||
|
||||
Follow the steps in the https://spring.io/guides/gs/producing-web-service/[companion guide], or just clone the https://github.com/spring-guides/gs-producing-web-service[repository] and run the service (e.g. using `mvn spring-boot:run`) from its `complete` directory. You can verify that is working by visiting http://localhost:8080/ws/countries.wsdl in your browser.
|
||||
|
||||
[[initial]]
|
||||
== Generate domain objects based on a WSDL
|
||||
|
||||
The interface to a SOAP web service is captured in a http://en.wikipedia.org/wiki/Web_Services_Description_Language[WSDL]. JAXB provides an easy means to generate Java classes from a WSDL (or rather: the XSD contained in the `<Types/>` section of the WSDL).
|
||||
The WSDL for the quote service can be found at http://www.webservicex.com/stockquote.asmx?WSDL.
|
||||
The WSDL for the country service can be found at http://localhost:8080/ws/countries.wsdl.
|
||||
|
||||
To generate Java classes from the WSDL in maven, you need the following plugin setup:
|
||||
|
||||
@@ -62,41 +65,41 @@ As gradle does not have a JAXB plugin (yet), it involves an ant task, which make
|
||||
|
||||
In both cases, the JAXB domain object generation process has been wired into the build tool's lifecycle so there are no extra steps to run.
|
||||
|
||||
== Create a stock market quotes service client
|
||||
== Create a country service client
|
||||
|
||||
To create a web service client, you simply have to extend the http://docs.spring.io/spring-ws/sites/2.0/apidocs/org/springframework/ws/client/core/support/WebServiceGatewaySupport.html[WebServiceGatewaySupport] class and code your operations:
|
||||
|
||||
`src/main/java/hello/QuoteClient.java`
|
||||
`src/main/java/hello/CountryClient.java`
|
||||
[source,java]
|
||||
----
|
||||
include::complete/src/main/java/hello/QuoteClient.java[]
|
||||
include::complete/src/main/java/hello/CountryClient.java[]
|
||||
----
|
||||
|
||||
The client contains one method: `getQuote` which does the actual SOAP exchange.
|
||||
The client contains one method: `getCountry` which does the actual SOAP exchange.
|
||||
|
||||
In this method, both the `GetQuote` and the `GetQuoteResponse` classes are derived from the WSDL and were generated in the JAXB generation process described in the previous step.
|
||||
It creates the `GetQuote` request object and sets it up with the `ticker` parameter.
|
||||
After printing out the ticker code, it uses the http://docs.spring.io/spring-ws/sites/2.0/apidocs/org/springframework/ws/client/core/WebServiceTemplate.html[WebServiceTemplate] supplied by the `WebServiceGatewaySupport` base class to do the actual SOAP exchange.
|
||||
It passes the `GetQuote` request object, as well as a `SoapActionCallback` to pass on a http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528[SOAPAction] header with the request, as the WSDL described that it needed this header in the `<soap:operation/>` elements.
|
||||
It casts the response into a `GetQuoteResponse` object, which is then returned.
|
||||
In this method, both the `GetCountryRequest` and the `GetCountryResponse` classes are derived from the WSDL and were generated in the JAXB generation process described in the previous step.
|
||||
It creates the `GetCountryRequest` request object and sets it up with the `country` parameter (the name of the country).
|
||||
After printing out the country name, it uses the http://docs.spring.io/spring-ws/sites/2.0/apidocs/org/springframework/ws/client/core/WebServiceTemplate.html[WebServiceTemplate] supplied by the `WebServiceGatewaySupport` base class to do the actual SOAP exchange.
|
||||
It passes the `GetCountryRequest` request object, as well as a `SoapActionCallback` to pass on a http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528[SOAPAction] header with the request, as the WSDL described that it needed this header in the `<soap:operation/>` elements.
|
||||
It casts the response into a `GetCountryResponse` object, which is then returned.
|
||||
|
||||
== Configuring web service components
|
||||
|
||||
Spring WS uses Spring Framework's OXM module which has the `Jaxb2Marshaller` to serialize and deserialize XML requests.
|
||||
|
||||
`src/main/java/hello/QuoteConfiguration.java`
|
||||
`src/main/java/hello/CountryConfiguration.java`
|
||||
[source,java]
|
||||
----
|
||||
include::complete/src/main/java/hello/QuoteConfiguration.java[]
|
||||
include::complete/src/main/java/hello/CountryConfiguration.java[]
|
||||
----
|
||||
|
||||
The `marshaller` is pointed at the collection of generated domain objects and will use them to both serialize and deserialize between XML and link:/understanding/POJO[POJOs].
|
||||
|
||||
The `quoteClient` is created and configured with the URI of the weather service shown up above. It is also configured to use the JAXB marshaller.
|
||||
The `countryClient` is created and configured with the URI of the country service shown up above. It is also configured to use the JAXB marshaller.
|
||||
|
||||
== Make the application executable
|
||||
|
||||
This application is packaged up to run from the console and retrieve the stock value for a given symbol.
|
||||
This application is packaged up to run from the console and retrieve the data for a given country name:
|
||||
|
||||
`src/main/java/hello/Application.java`
|
||||
[source,java]
|
||||
@@ -104,7 +107,7 @@ This application is packaged up to run from the console and retrieve the stock v
|
||||
include::complete/src/main/java/hello/Application.java[]
|
||||
----
|
||||
|
||||
The `main()` method defers to the http://docs.spring.io/spring-boot/docs/{spring_boot_version}/api/org/springframework/boot/SpringApplication.html[`SpringApplication`] helper class, providing `QuoteConfiguration.class` as an argument to its `run()` method. This tells Spring to read the annotation metadata from `QuoteConfiguration` and to manage it as a component in the link:/understanding/application-context[Spring application context].
|
||||
The `main()` method defers to the http://docs.spring.io/spring-boot/docs/{spring_boot_version}/api/org/springframework/boot/SpringApplication.html[`SpringApplication`] helper class, providing `CountryConfiguration.class` as an argument to its `run()` method. This tells Spring to read the annotation metadata from `CountryConfiguration` and to manage it as a component in the link:/understanding/application-context[Spring application context].
|
||||
|
||||
NOTE: This application is hard coded to look up symbol 'MSFT' which correspond to Microsoft Corporation. Towards the end of this guide, you'll see how to plug in a different symbol without editing the code.
|
||||
|
||||
@@ -116,18 +119,17 @@ include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/
|
||||
Logging output is displayed. The service should be up and running within a few seconds.
|
||||
|
||||
```
|
||||
Requesting quote for MSFT
|
||||
Requesting country data for Spain
|
||||
|
||||
<StockQuotes><Stock><Symbol>MSFT</Symbol><Last>62.70</Last>...</StockQuotes>
|
||||
<getCountryRequest><name>Spain</name>...</getCountryRequest>
|
||||
```
|
||||
|
||||
You can plug in a different ticker by typing `java -jar build/libs/gs-consuming-web-service-0.1.0.jar ORCL`
|
||||
You can plug in a different country by typing `java -jar build/libs/gs-consuming-web-service-0.1.0.jar Poland`
|
||||
|
||||
```
|
||||
Requesting quote for ORCL
|
||||
|
||||
<StockQuotes><Stock><Symbol>ORCL</Symbol><Last>39.26</Last>...</StockQuotes>
|
||||
Requesting location for Poland
|
||||
|
||||
<getCountryRequest><name>Poland</name>...</getCountryRequest>
|
||||
```
|
||||
|
||||
== Summary
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.8.RELEASE")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ repositories {
|
||||
task genJaxb {
|
||||
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
|
||||
ext.classesDir = "${buildDir}/classes/jaxb"
|
||||
ext.schema = "http://www.webservicex.com/stockquote.asmx?WSDL"
|
||||
ext.schema = "http://localhost:8080/ws/countries.wsdl"
|
||||
|
||||
outputs.dir classesDir
|
||||
|
||||
|
||||
2
complete/mvnw
vendored
2
complete/mvnw
vendored
@@ -8,7 +8,7 @@
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
|
||||
2
complete/mvnw.cmd
vendored
2
complete/mvnw.cmd
vendored
@@ -7,7 +7,7 @@
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework</groupId>
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
<version>2.0.8.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -51,7 +51,7 @@
|
||||
<generatePackage>hello.wsdl</generatePackage>
|
||||
<schemas>
|
||||
<schema>
|
||||
<url>http://www.webservicex.com/stockquote.asmx?WSDL</url>
|
||||
<url>http://localhost:8080/ws/countries.wsdl</url>
|
||||
</schema>
|
||||
</schemas>
|
||||
</configuration>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
package hello;
|
||||
|
||||
import hello.wsdl.GetQuoteResponse;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import hello.wsdl.GetCountryResponse;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
@@ -16,15 +16,15 @@ public class Application {
|
||||
}
|
||||
|
||||
@Bean
|
||||
CommandLineRunner lookup(QuoteClient quoteClient) {
|
||||
CommandLineRunner lookup(CountryClient quoteClient) {
|
||||
return args -> {
|
||||
String ticker = "MSFT";
|
||||
String country = "Spain";
|
||||
|
||||
if (args.length > 0) {
|
||||
ticker = args[0];
|
||||
country = args[0];
|
||||
}
|
||||
GetQuoteResponse response = quoteClient.getQuote(ticker);
|
||||
System.err.println(response.getGetQuoteResult());
|
||||
GetCountryResponse response = quoteClient.getCountry(country);
|
||||
System.err.println(response.getCountry().getCurrency());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
32
complete/src/main/java/hello/CountryClient.java
Normal file
32
complete/src/main/java/hello/CountryClient.java
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
package hello;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
|
||||
import org.springframework.ws.soap.client.core.SoapActionCallback;
|
||||
|
||||
import hello.wsdl.GetCountryRequest;
|
||||
import hello.wsdl.GetCountryResponse;
|
||||
|
||||
public class CountryClient extends WebServiceGatewaySupport {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CountryClient.class);
|
||||
|
||||
public GetCountryResponse getCountry(String country) {
|
||||
|
||||
GetCountryRequest request = new GetCountryRequest();
|
||||
request.setName(country);
|
||||
|
||||
log.info("Requesting location for " + country);
|
||||
|
||||
GetCountryResponse response = (GetCountryResponse) getWebServiceTemplate()
|
||||
.marshalSendAndReceive("http://localhost:8080/ws/countries", request,
|
||||
new SoapActionCallback(
|
||||
"http://spring.io/guides/gs-producing-web-service/GetCountryRequest"));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
|
||||
@Configuration
|
||||
public class QuoteConfiguration {
|
||||
public class CountryConfiguration {
|
||||
|
||||
@Bean
|
||||
public Jaxb2Marshaller marshaller() {
|
||||
@@ -18,9 +18,9 @@ public class QuoteConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public QuoteClient quoteClient(Jaxb2Marshaller marshaller) {
|
||||
QuoteClient client = new QuoteClient();
|
||||
client.setDefaultUri("http://www.webservicex.com/stockquote.asmx");
|
||||
public CountryClient countryClient(Jaxb2Marshaller marshaller) {
|
||||
CountryClient client = new CountryClient();
|
||||
client.setDefaultUri("http://localhost:8080/ws");
|
||||
client.setMarshaller(marshaller);
|
||||
client.setUnmarshaller(marshaller);
|
||||
return client;
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
package hello;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
|
||||
import org.springframework.ws.soap.client.core.SoapActionCallback;
|
||||
|
||||
import hello.wsdl.GetQuote;
|
||||
import hello.wsdl.GetQuoteResponse;
|
||||
|
||||
public class QuoteClient extends WebServiceGatewaySupport {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(QuoteClient.class);
|
||||
|
||||
public GetQuoteResponse getQuote(String ticker) {
|
||||
|
||||
GetQuote request = new GetQuote();
|
||||
request.setSymbol(ticker);
|
||||
|
||||
log.info("Requesting quote for " + ticker);
|
||||
|
||||
GetQuoteResponse response = (GetQuoteResponse) getWebServiceTemplate()
|
||||
.marshalSendAndReceive("http://www.webservicex.com/stockquote.asmx",
|
||||
request,
|
||||
new SoapActionCallback("http://www.webserviceX.NET/GetQuote"));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.8.RELEASE")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ repositories {
|
||||
task genJaxb {
|
||||
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
|
||||
ext.classesDir = "${buildDir}/classes/jaxb"
|
||||
ext.schema = "http://www.webservicex.com/stockquote.asmx?WSDL"
|
||||
ext.schema = "http://localhost:8080/ws/countries.wsdl"
|
||||
|
||||
outputs.dir classesDir
|
||||
|
||||
|
||||
2
initial/mvnw
vendored
2
initial/mvnw
vendored
@@ -8,7 +8,7 @@
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
|
||||
2
initial/mvnw.cmd
vendored
2
initial/mvnw.cmd
vendored
@@ -7,7 +7,7 @@
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework</groupId>
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
<version>2.0.8.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -51,7 +51,7 @@
|
||||
<generatePackage>hello.wsdl</generatePackage>
|
||||
<schemas>
|
||||
<schema>
|
||||
<url>http://www.webservicex.com/stockquote.asmx?WSDL</url>
|
||||
<url>http://localhost:8080/ws/countries.wsdl</url>
|
||||
</schema>
|
||||
</schemas>
|
||||
</configuration>
|
||||
|
||||
1
test/.gitignore
vendored
Normal file
1
test/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
gs-producing*/
|
||||
@@ -1,6 +1,11 @@
|
||||
#!/bin/sh
|
||||
cd $(dirname $0)
|
||||
|
||||
git clone https://github.com/spring-guides/gs-producing-web-service
|
||||
(cd gs-producing-web-service/complete; ./mvnw install; ./mvnw spring-boot:run &)
|
||||
|
||||
sleep 10
|
||||
|
||||
cd ../complete
|
||||
|
||||
mvn clean package
|
||||
@@ -33,4 +38,6 @@ exit $ret
|
||||
fi
|
||||
rm -rf build
|
||||
|
||||
pkill -f spring-boot:run
|
||||
|
||||
exit
|
||||
|
||||
Reference in New Issue
Block a user