To start with we assume that we have access to a remote WebService, from which we can easily download the WSDL file. For example, let's take a simple WebService that provides weather forecast: http://www.restfulwebservices.net/wcf/WeatherForecastService.svc?wsdl.
The code samples used for this example can be found here.
Generating the WebService client Java source files with Maven
The wsimport
goal from the Maven plugin jaxws-maven-plugin
allows you to generate the WebService client Java source files given a WSDL file.
The WSDL file can either be accessed remotely using an URL or locally using a directory.
Obviously it is better to point at a local (previously downloaded) WSDL file to ensure reproducibility of the build.
For instance, copy http://www.restfulwebservices.net/wcf/WeatherForecastService.svc?wsdl to src/main/resources/wsdls
in a Nuxeo project and use the following code in your pom.xml
:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlDirectory>src/main/resources/wsdls</wsdlDirectory>
<sourceDestDir>${project.build.directory}/generated-sources/wsimport</sourceDestDir>
</configuration>
</execution>
</executions>
</plugin>
When you'll build the project, all WSDL files in src/main/resources/wsdls
will be parsed and the associated Java source files generated in ${project.build.directory}/generated-sources/wsimport
.
The jaxws:wsimport
goal is automatically executed within the life cycle phase generate-sources
, ie. before the compile
phase. This way, running mvn clean install
first generates the source files and then compiles them.
Often a WSDL file needs to import one or more XSD schemas, using the <xsd:import>
directive.
Let's take this example:
<xsd:import
**schemaLocation="http://www.restfulwebservices.net/wcf/WeatherForecastService.svc?xsd=xsd0"**
namespace="http://www.restfulwebservices.net/ServiceContracts/2008/01"/>
If your WSDL file is accessed locally, you also have to download all the XSD schemas referenced by the WSDL and use a relative path for the schemaLocation
attribute of the <xsd:import>
directives prior to building your project.
Assuming that the XSD schema WeatherForecastService.xsd
has been downloaded in src/main/resources/wsdls/xsdschemas
, this is what you get:
<xsd:import
**schemaLocation="xsdschemas/WeatherForecastService.xsd"**
namespace="http://www.restfulwebservices.net/ServiceContracts/2008/01"/>
.
Documentation about wsimport
is available here: http://jax-ws-commons.java.net/jaxws-maven-plugin/wsimport-mojo.html.
Documentation about using JAX-WS with Maven is available here: http://blogs.oracle.com/enterprisetechtips/entry/using_jax_ws_with_maven.
Getting an Instance of the WebService Client
Once the Java source files have been generated and compiled, you can use them as a third-party library:
WeatherForecastService wfs = new WeatherForecastService(
new URL("http://www.restfulwebservices.net/wcf/WeatherForecastService.svc?wsdl"),
new QName("http://www.restfulwebservices.net/ServiceContracts/2008/01", "WeatherForecastService"));
IWeatherForecastService iwfs = wfs.getBasicHttpBindingIWeatherForecastService();
The (slightly) tricky part here is to find the actual WebService client in the generated classes and the method it provides to get an instance of the WebService client interface.
The actual WebService client is the class with the following annotation: @WebServiceClient(name = "WeatherForecastService",... In our example:
WeatherForecastService
- The URL is the one of the WSDL file.
- To build the
QName
, we use thetargetNamespace
andname
attributes of the<wsdl:definitions>
element in the WSDL file. In our example:<wsdl:definitions name="WeatherForecastService" targetNamespace="http://www.restfulwebservices.net/ServiceContracts/2008/01"...
.
The WebService client interface is the class with the following annotation: @WebService(name = "IWeatherForecastService",... In our example:
IWeatherForecastService
The
WeatherForecastService
class offers the methodgetBasicHttpBindingIWeatherForecastService()
that returns an object of typeIWeatherForecastService
.
Calling a WebService Method
Finally, you can call any method available in the WebService client interface, for instance IWeatherForecastService#getCitiesByCountry(String country)
which returns the cities of a given country.
ArrayOfstring cities = iwfs.getCitiesByCountry("FRANCE");
String message = "Cities of country FRANCE: " + cities.getString();
You can learn here how to build a server-side SOAP based WebService in Nuxeo.
Advanced Client Configuration Using a Configuration XML File
If you are looking how to create some advanced client configuration, since Apache CXF, you'll need some dependencies. The configuration behavior is the same as the server part, and described in the advanced configuration section of the Building a SOAP-Based WebService in the Nuxeo Platform.