jws

JAX-WS Client from WSDL Example

In this example, we demonstrate how to generate a JAX-WS client from a WSDL file.

1. Introduction

Web services are software applications that exchange
messages over the internet.  A web
service client sends a request and the web service provider returns a response.

In general, there are two types of web services, SOAP-based
and RESTful-based. In Java, the specifications used for these two types of
services are JAX-WS and JAX-RS, respectively.

A WSDL file is used to describe a SOAP-based web
service.  It specifies the operations of
the service, their parameters and types, and the endpoints available to invoke
those operations. 

There are tools available for generating the necessary stub code used for creating server and client applications. These tools typically work by parsing a WSDL file.

Apache CXF is a framework for developing and running JAX-WS
and JAX-RS type web services.  There are
several utilities included in the Apache CXF distribution for working with WSDL
files.  Among these are the following:

  • wsdl2java – accepts a WSDL document as input and generates annotated Java code from which to implement a service or client.
  • wsdl2js – accepts a WSDL document as input and generates Javascript code from which to implement a service.
  • wsdl2service -generates a WSDL file containing an HTTP or JMS service definition from an existing WSDL document containing a binding element.

In this example, we will use the wsdl2java utility to generate stub code and a simple web service client that leverages the stub code. The Maven cxf-codegen-plugin will be used to configure and execute the wsdl2java utility.

1.1 Tools Used in this Example

  • Eclipse IDE for Enterprise Java Developer 2018-12
  • Maven 3.3.9 (Embedded in Eclipse)
  • Spring Tools 4 – for Spring Boot
  • Tomcat 9.0

Spring Tools 4 for Spring Boot is a set of plugins for Eclipse that support building and running Spring Boot applications. You can add Spring Tools 4 to your existing Eclipse installation by going to the Eclipse Marketplace and searching for “Spring Tools 4”.

2. JAX-WS Client from WSDL Example

2.1 Download the Archive

Begin by downloading the Client-WSDL zip file from the download section and extracting it to a folder of your choice.

2.2 Create the Client Project

Next, create a Maven project for the client application.

  1. Select New -> Other…  In the “Select a wizard” windowselect Maven Project from the Maven section and click Next.
  2. Select “Create a simple project (skip archetype selection)” and click Next.
  3. Enter a Group Id and Artifact Id. Select “jar” for Packaging and a Name and Description if desired. Click Finish.
JAX-WS Client from WSDL - Maven Project
New Maven Project

2.3 Copy the WSDL File

Create a folder named wsdl under scr/main/resources.  Copy the Quotes.wsdl file that was extracted from the zip file and place it in the wsdl folder. 

JAX-WS Client from WSDL - Directory Structure for WSDL File
Directory Structure for WSDL File

Let’s take a look at the Quote.wsdl file.

Quote.wsdl

 
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:tns="http://examples.javacodegeeks.com/"
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
	name="RandomQuoteService"
	targetNamespace="http://examples.javacodegeeks.com/">
	<wsdl:types>
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
			xmlns:tns="http://examples.javacodegeeks.com/"
			elementFormDefault="unqualified"
			targetNamespace="http://examples.javacodegeeks.com/" version="1.0">

			<xs:element name="getQuote" type="tns:getQuote" />

			<xs:element name="getQuoteResponse"
				type="tns:getQuoteResponse" />

			<xs:complexType name="getQuote">
				<xs:sequence />
			</xs:complexType>

			<xs:complexType name="getQuoteResponse">
				<xs:sequence>
					<xs:element minOccurs="0" name="return" type="xs:string" />
				</xs:sequence>
			</xs:complexType>

		</xs:schema>
	</wsdl:types>
	<wsdl:message name="getQuoteResponse">
		<wsdl:part element="tns:getQuoteResponse" name="parameters">
		</wsdl:part>
	</wsdl:message>
	<wsdl:message name="getQuote">
		<wsdl:part element="tns:getQuote" name="parameters">
		</wsdl:part>
	</wsdl:message>
	<wsdl:portType name="RandomQuote">
		<wsdl:operation name="getQuote">
			<wsdl:input message="tns:getQuote" name="getQuote">
			</wsdl:input>
			<wsdl:output message="tns:getQuoteResponse"
				name="getQuoteResponse">
			</wsdl:output>
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="RandomQuoteServiceSoapBinding"
		type="tns:RandomQuote">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" />
		<wsdl:operation name="getQuote">
			<soap:operation soapAction="" style="document" />
			<wsdl:input name="getQuote">
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output name="getQuoteResponse">
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="RandomQuoteService">
		<wsdl:port binding="tns:RandomQuoteServiceSoapBinding"
			name="RandomQuotePort">
			<soap:address
				location="http://localhost:8080/soapservice/services/quoteService" />
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

The WSDL file describes a simple web service with one operation (getQuote) that returns a String and one port (RandomQuote) configured for the HTTP protocol.  The service endpoint is set to http://localhost:8080/soapservice/services/quoteService though this can be configured at runtime by the web service implementor.

2.4 Add the Maven CXF code-gen Plugin

Open the pom.xml file and add the Maven cxf-codegen-plugin.

pom.xml

<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">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>soapclient</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.cxf</groupId>
				<artifactId>cxf-codegen-plugin</artifactId>
				<version>3.2.7</version>
				<executions>
					<execution>
						<id>generate-sources</id>
						<phase>generate-sources</phase>
						<configuration>
							<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
							<wsdlOptions>
								<wsdlOption>
									<wsdl>${basedir}/src/main/resources/wsdl/Quotes.wsdl</wsdl>
									<wsdlLocation>classpath:wsdl/Quotes.wsdl</wsdlLocation>
									<extraargs>
										<extraarg>-client</extraarg>
									</extraargs>
								</wsdlOption>
							</wsdlOptions>
						</configuration>
						<goals>
							<goal>wsdl2java</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

As the name implies, the Maven CXF codegen plugin generates code.  It will execute CXF command-line tools through Maven goals. Here we are specifying that the wsdl2java tool is to be executed.  We are also specifying that it should be executed during the Maven generate-sources phase.  The output directory for the generated classes is specified with the <sourceRoot> element.

The wsdl2java tool requires, at the least, the location of the WSDL file as an argument.  This is specified with the <wsdl> element inside the <wsdlOption> element.  We include the <wsdlLocation> element and prefix the location with classpath: so that the generated classes use this value rather than the absolute path of the WSDL file in the file system.

Additional options can be specified using the <extraargs> element.  We are directing wsdl2java to use the -client option, which will generate a simple Java client.  For a list of other wsdl2java options, visit the CXF Apache documentation here.

The plugin configuration uses two Maven properties:

  • ${basedir} – represents the root folder of the project.
  • ${project.build.directory} – references the target folder, which is the default for Maven generated artifacts.

When you save the file, the wsdl2java goal will be executed as part of the generate-sources phase and the following Java classes will be generated in the target/generated/cxf directory:

  • GetQuote.java
  • GetQuoteResponse.java
  • ObjectFactory.java
  • package-info.java
  • RandomQuote_RandomQuotePort_Client.java
  • RandomQuote.java
  • RandomQuoteService.java

You can run Maven > Update Project… to remove the error.

2.5 The Generated Client Application

Open RandomQuote_RandomQuotePort_Client.java to view its code.

RandomQuote_RandomQuotePort_Client.java

package com.javacodegeeks.examples;

/**
 * Please modify this class to meet your needs
 * This class is not complete
 */

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

/**
 * This class was generated by Apache CXF 3.2.7
 * 2019-02-10T13:05:02.753-08:00
 * Generated source version: 3.2.7
 *
 */
public final class RandomQuote_RandomQuotePort_Client {

    private static final QName SERVICE_NAME = new QName("http://examples.javacodegeeks.com/", "RandomQuoteService");

    private RandomQuote_RandomQuotePort_Client() {
    }

    public static void main(String args[]) throws java.lang.Exception {
        URL wsdlURL = RandomQuoteService.WSDL_LOCATION;
        if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
            File wsdlFile = new File(args[0]);
            try {
                if (wsdlFile.exists()) {
                    wsdlURL = wsdlFile.toURI().toURL();
                } else {
                    wsdlURL = new URL(args[0]);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

        RandomQuoteService ss = new RandomQuoteService(wsdlURL, SERVICE_NAME);
        RandomQuote port = ss.getRandomQuotePort();

        {
        System.out.println("Invoking getQuote...");
        java.lang.String _getQuote__return = port.getQuote();
        System.out.println("getQuote.result=" + _getQuote__return);


        }

        System.exit(0);
    }

}

The main method uses the URL from the generated RandomQuoteService class. 
(RandomQuoteService looks up the WSDL URL from the classpath.)  You can override this behavior by passing the location of the WSDL as an argument to the client application.

The service class is instantiated using
the RandomQuoteService(URL wsdlLocation, QName serviceName) constructor.  Next,
the service endpoint interface (SEI) is retrieved from
the service with a call to getRandomQuotePort(). Finally, the getQuote() operation is invoked and the response is printed out to
the console.

2.6 Import the Web Service Project

Click File -> Import… and select Projects from Folder or Archive.  Click Next.

JAX-WS Client from WSDL - Projects from Folder or Archive
Select Projects from Folder or Archive

Click on the Archive… button and select the soapwebservice.zip file from the folder where the archive was extracted.  Select the Eclipse project from the list and click Finish.

JAX-WS Client from WSDL - Eclipse Project
Import the Eclipse Project

2.7 Start the Web Service

Right-click the soapwebservice project in Project Explorer and select Run As > Spring Boot App.

Spring Boot App Output

 
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-11 16:33:08.480  INFO 2352 --- [           main] c.j.e.soap.SoapwebserviceApplication     : Starting SoapwebserviceApplication on Gilbert-THINK with PID 2352 (C:\Users\Gilbert\workspaces\examples\soapwebservice\target\classes started by Gilbert in C:\Users\Gilbert\workspaces\examples\soapwebservice)
2019-02-11 16:33:08.486  INFO 2352 --- [           main] c.j.e.soap.SoapwebserviceApplication     : No active profile set, falling back to default profiles: default
2019-02-11 16:33:11.022  INFO 2352 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-02-11 16:33:11.053  INFO 2352 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-02-11 16:33:11.053  INFO 2352 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.14]
2019-02-11 16:33:11.061  INFO 2352 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_161\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Java/jdk1.8.0_11/bin/../jre/bin/server;C:/Java/jdk1.8.0_11/bin/../jre/bin;C:/Java/jdk1.8.0_11/bin/../jre/lib/amd64;C:\Program Files (x86)\Intel\iCLS Client\;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\IBM\WebSphere MQ\java\lib;C:\Program Files (x86)\IBM\WebSphere MQ\java\lib64;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\PROGRA~2\IBM\SQLLIB\BIN;C:\PROGRA~2\IBM\SQLLIB\FUNCTION;C:\PROGRA~2\IBM\SQLLIB\SAMPLES\REPL;C:\Java\jdk1.8.0_11\bin;C:\Program Files (x86)\IBM\WebSphere\AppServer\bin;C:\Program Files (x86)\IBM\WebSphere MQ\bin64;C:\Program Files (x86)\IBM\WebSphere MQ\bin;C:\Program Files (x86)\IBM\WebSphere MQ\tools\c\samples\bin;C:\Program Files\Lenovo\Fingerprint Manager Pro\;C:\Program Files (x86)\Common Files\lenovo\easyplussdk\bin;C:\Program Files (x86)\Lenovo\Access Connections\;C:\OpenShift;C:\Program Files\apache-maven-3.5.2\bin;C:\Program Files (x86)\Intel\UCRT\;C:\Program Files\Intel\UCRT\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Git\cmd;C:\Program Files\PuTTY\;C:\Program Files (x86)\Brackets\command;C:\apache2\bin;C:\lighttpd;C:\Program Files\SourceGear\Common\DiffMerge\;C:\Ruby24-x64\bin;C:\Users\Gilbert\AppData\Local\atom\bin;C:\Users\Gilbert\Desktop;;.]
2019-02-11 16:33:11.188  INFO 2352 --- [           main] o.a.c.c.C.[.[localhost].[/soapservice]   : Initializing Spring embedded WebApplicationContext
2019-02-11 16:33:11.189  INFO 2352 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2592 ms
2019-02-11 16:33:11.904  INFO 2352 --- [           main] o.a.c.w.s.f.ReflectionServiceFactoryBean : Creating Service {http://soap.examples.javacodegeeks.com/}RandomQuoteImplService from class com.javacodegeeks.examples.RandomQuote
2019-02-11 16:33:12.790  INFO 2352 --- [           main] org.apache.cxf.endpoint.ServerImpl       : Setting the server's publish address to be /quoteService
2019-02-11 16:33:13.178  INFO 2352 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-02-11 16:33:13.537  INFO 2352 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/soapservice'
2019-02-11 16:33:13.542  INFO 2352 --- [           main] c.j.e.soap.SoapwebserviceApplication     : Started SoapwebserviceApplication in 6.112 seconds (JVM running for 7.745)

2.8 Run the Client Application

Right-click RandomQuote_RandomQuotePort_Client and select Run As -> Java Application. You will see a successful response in the console.

Web Service Client Output

 
Invoking getQuote...
getQuote.result=I think therefore I am

3. JAX-WS Client from WSDL – Summary

In this post, we demonstrated how to generate a web service client using the wsdl2java utility and the Maven CXF codegen plugin.

4. Download the Source Code

This was a JAX-WS Client from WSDL Example.

Download
You can download the full source code of this example here: JAX-WS Client from WSDL Example

Gilbert Lopez

Gilbert Lopez is an application developer and systems integration developer with experience building business solutions for large and medium-sized companies. He has worked on many Java EE projects. His roles have included lead developer, systems analyst, business analyst and consultant. Gilbert graduated from California State University in Los Angeles with a Bachelor of Science degree in Business.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ivan
ivan
5 years ago

Why i try to running the client application, I always get a message “The server sent HTTP status code 406: null” ?

manish
manish
4 years ago

Hi,

I used this approach to generate the java code (wsdl2java) and getting response in my eclipse, but when converted this code as a jar and using in weblogic every time getting
Runtime exception.

“java.lang.RuntimeException: MASM0015: Class [ com.sun.xml.ws.assembler.jaxws.HandlerTubeFactory ] does not implement [ com.sun.xml.internal.ws.assembler.dev.TubeFactory ] interface”

Moved all the dependent jars too in weblogic classpath but no luck.

Back to top button