jws

JAX-WS Change Endpoint Example

In this example, we will demonstrate how to change the service endpoint in a Java web service client application.

1. Introduction

A web service (which is described in a WSDL file) can have one or more endpoints.  A web service endpoint is a URL used to locate and access a web service.  The endpoint is derived from the port and binding elements of the WSDL and is defined in the service element.  Web service clients use endpoints to access and invoke operations on a service.

There are several techniques that can be used to invoke web service operations by Java client applications.  One common method is to use the ‘wsimport’ command-line tool (part of the Java SE) to generate the client code.

The ‘wsimport’ tool generates artifacts based on the WSDL of the target web service.  The artifacts include stubs that function as proxies for accessing the web service, which is typically running on another computer.

The endpoint URL is hard-coded in the generated Service class (described in the example below).  There are times when the endpoint of web service has changed, and you don’t have access to the WSDL in order to regenerate the client code.  In this example, we will show how to change the service endpoint in a client application by using a Service class constructor.

1.1 Tools Used in this Example

  • Eclipse IDE for Enterprise Java Developer 2018-12
  • Tomcat 9.0

2. JAX-WS Change Endpoint Example

2.1 Import the Web Service Project

Begin by downloading the Random Quote zip file from the download section.  Next, import the Random Quote Project into your workspace with the following steps:

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

JAX-WS Change Endpoint - Projects from Folder or Archive
Select Projects from Folder or Archive

Click on the Archive… button and select the Random-Quote.zip file.  Select the Eclipse project from the list and click Finish.

JAX-WS Change Endpoint - Import the Eclipse Project
Import the Eclipse Project

2.2 Configuring the Service Endpoint

The Random Quote web service was developed using the bottom-up approach.  Therefore, we can set the service endpoint URL in a configuration file.  Since we are using Apache CXF as the web service stack, we configured the endpoint in the cxf-servlet.xml file.  The endpoint is specified in the address attribute of the jaxws:server element.

cxf-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:cxf="http://cxf.apache.org/core"
	xmlns:soap="http://cxf.apache.org/bindings/soap"
	xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<jaxws:server id="quoteService" serviceClass="com.javacodegeeks.examples.RandomQuote" address="/getQuote">
		<jaxws:serviceBean>
			<bean class="com.javacodegeeks.examples.RandomQuoteImpl" />
		</jaxws:serviceBean>
	</jaxws:server>

</beans>

Note: If we were using the top-down development approach we would configure the endpoint directly in the service element of the WSDL contract.

2.3 Start the Random Quote Web Service

Right-click the project and select Run As -> Run on Server. Select the Tomcat server and click “Finish”. When the application starts, you will see the “Available SOAP services” page. 

JAX-WS Change Endpoint - RandomQuote Web Service
RandomQuote Web Service

You will notice that the endpoint address for the RandomQuote service is http://localhost:8080/JaxWsRandomQuote/getQuote. Click on WSDL link to view the WSDL file.

Random Quote WSDL File

<?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/JaxWsRandomQuote/getQuote"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

You can see that the endpoint URL is defined in the location attribute of the soap:address element.  (The WSDL file is generated on-the-fly by the web services stack.)

2.4 Create the Web Service Client

We will create a stand-alone Java client application. Start by creating a Java project for the client code.

  1. Select New -> Other…  In the “Select a wizard” window, select 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 Change Endpoint - Random Quote Client Maven Project
Random Quote Client Maven Project

2.5 Generate the Web Service Client Code

Next, generate the web service client code:

  1. Expand the client project, right-click src/main/java and select Show In -> Terminal.
  2. Copy the web service WSDL URL from your browser. It should look like this: http://localhost:8080/JaxWsRandomQuote/getQuote?wsdl.
  3. Run the wsimport command (shown below) to generate the client code.  (Replace <WSDL_URL> with the one copied from your browser.) Note: The web service must be running when you run the wsimport command.
wsimport -keep -p com.javacodegeeks.examples.client <WSDL_URL>

The wsimport command-line tool is included in the Java SE. The -keep option saves the Java source files and the -p options specifies the Java package we want to use for the generated files.

Running the wsimport command will generate the following files:

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

2.6 View the Service Class

Open the RandomQuoteService.java file.

RandomQuoteService.java

package com.javacodegeeks.examples.client;

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.9-b130926.1035
 * Generated source version: 2.2
 * 
 */
@WebServiceClient(name = "RandomQuoteService", targetNamespace = "http://examples.javacodegeeks.com/", wsdlLocation = "http://localhost:8080/JaxWsRandomQuote/getQuote?wsdl")
public class RandomQuoteService
    extends Service
{

    private final static URL RANDOMQUOTESERVICE_WSDL_LOCATION;
    private final static WebServiceException RANDOMQUOTESERVICE_EXCEPTION;
    private final static QName RANDOMQUOTESERVICE_QNAME = new QName("http://examples.javacodegeeks.com/", "RandomQuoteService");

    static {
        URL url = null;
        WebServiceException e = null;
        try {
            url = new URL("http://localhost:8080/JaxWsRandomQuote/getQuote?wsdl");
        } catch (MalformedURLException ex) {
            e = new WebServiceException(ex);
        }
        RANDOMQUOTESERVICE_WSDL_LOCATION = url;
        RANDOMQUOTESERVICE_EXCEPTION = e;
    }

    public RandomQuoteService() {
        super(__getWsdlLocation(), RANDOMQUOTESERVICE_QNAME);
    }

    public RandomQuoteService(WebServiceFeature... features) {
        super(__getWsdlLocation(), RANDOMQUOTESERVICE_QNAME, features);
    }

    public RandomQuoteService(URL wsdlLocation) {
        super(wsdlLocation, RANDOMQUOTESERVICE_QNAME);
    }

    public RandomQuoteService(URL wsdlLocation, WebServiceFeature... features) {
        super(wsdlLocation, RANDOMQUOTESERVICE_QNAME, features);
    }

    public RandomQuoteService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public RandomQuoteService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
        super(wsdlLocation, serviceName, features);
    }

    /**
     * 
     * @return
     *     returns RandomQuote
     */
    @WebEndpoint(name = "RandomQuotePort")
    public RandomQuote getRandomQuotePort() {
        return super.getPort(new QName("http://examples.javacodegeeks.com/", "RandomQuotePort"), RandomQuote.class);
    }

    /**
     * 
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the features parameter will have their default values.
     * @return
     *     returns RandomQuote
     */
    @WebEndpoint(name = "RandomQuotePort")
    public RandomQuote getRandomQuotePort(WebServiceFeature... features) {
        return super.getPort(new QName("http://examples.javacodegeeks.com/", "RandomQuotePort"), RandomQuote.class, features);
    }

    private static URL __getWsdlLocation() {
        if (RANDOMQUOTESERVICE_EXCEPTION!= null) {
            throw RANDOMQUOTESERVICE_EXCEPTION;
        }
        return RANDOMQUOTESERVICE_WSDL_LOCATION;
    }

}

Notice that the endpoint URL is hard-coded in the static code block (line 32). Also, notice that there are several constructors available to instantiate the RandomQuoteService class.

2.7 Create the Client Application

Create a Java class with the following code:

RandomQuoteClient.java

package com.javacodegeeks.examples.client;

public class RandomQuoteClient {

	public static void main(String[] args) {
		RandomQuoteService service = new RandomQuoteService();
		RandomQuote port = service.getRandomQuotePort();
		
		System.out.println("Quote of the day: " + port.getQuote());
	}

}

First, we instantiate a service client class using the RandomQuoteService no-argument constructor on line 6. We then get the service endpoint interface (SEI) from the service object on line 7. Finally, we send the request and print out the response on line 9.

2.8 Test the Web Service Client

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

Web Service Client Output

Quote of the day: I think therefore I am

2.9 Modify the Web Service Endpoint

Open cxf-servlet.xml and change the address attribute of the jaxws:server element from /getQuote to /getRandomQuote:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xmlns:cxf="http://cxf.apache.org/core"
	xmlns:soap="http://cxf.apache.org/bindings/soap"
	xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<jaxws:server id="quoteService" serviceClass="com.javacodegeeks.examples.RandomQuote" address="/getRandomQuote">
		<jaxws:serviceBean>
			<bean class="com.javacodegeeks.examples.RandomQuoteImpl" />
		</jaxws:serviceBean>
	</jaxws:server>

</beans>

Restart the server and reload the web service in your browser.   

JAX-WS Change Endpoint - Updated Endpoint
Updated Endpoint for the RandomQuote Web Service

You will notice that the endpoint has changed.  If you run the client now, you will get an exception.

Web Service Client Exception

Exception in thread "main" javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://localhost:8080/JaxWsDepencencies/getQuote?wsdl. It failed with: 
	http://localhost:8080/JaxWsDepencencies/getQuote?wsdl.
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:250)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:231)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:194)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:163)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:348)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:306)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:215)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:196)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.(WSServiceDelegate.java:192)
	at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
	at javax.xml.ws.Service.(Service.java:77)
	at com.javacodegeekses.client.RandomQuoteServiceService.(RandomQuoteServiceService.java:42)
	at com.javacodegeekses.client.QuoteClient.main(QuoteClient.java:6)
Caused by: java.io.FileNotFoundException: http://localhost:8080/JaxWsDepencencies/getQuote?wsdl
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1890)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
	at java.net.URL.openStream(URL.java:1045)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:984)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:385)
	at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:216)
	... 11 more

We are getting an exception
because the no-argument constructor is using the hard-coded value, which is no
longer valid because the web service endpoint has changed.  In order to fix this, we will need to modify
the client application.

2.10 Modify the Client

We can use the RandomQuoteService(URL wsdlLocation) constructor to override the hard-coded endpoint   Modify the client application by passing in the new endpoint URL to the constructor:

RandomQuoteClient.java

package com.javacodegeeks.examples.client;

import java.net.MalformedURLException;
import java.net.URL;

public class RandomQuoteClient {

	public static void main(String[] args) throws MalformedURLException {
		RandomQuoteService service = new RandomQuoteService(
				new URL("http://localhost:8080/JaxWsRandomQuote/getRandomQuote"));
		RandomQuote port = service.getRandomQuotePort();

		System.out.println("Quote of the day: " + port.getQuote());
	}

}

If you run the client application again, you will get a successful response.

Web Service Client Output

Quote of the day: It was the best of times, it was the worst of times...

3. Summary

In this post, we demonstrated how to change a web service endpoint in a Java client application.

4. Download the Source Code

This was a JAX-WS Change Endpoint Example.

Download

You can download the full source code of this example here:

JAX-WS Change Endpoint 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.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Otto
Otto
3 years ago

clean, detailed, good tutorial post

Back to top button