Red Hat Training

A Red Hat training course is available for Red Hat Fuse

Chapter 6. Finding WSDL at Runtime

Abstract

Hard coding the location of WSDL documents into an application is not scalable. In real deployment environments, you will want to allow the WSDL document's location be resolved at runtime. Apache CXF provides a number of tools to make this possible.
When developing consumers using the JAX-WS APIs you are must provide a hard coded path to the WSDL document that defines your service. While this is OK in a small environment, using hard coded paths does not translate to enterprise deployments.
To address this issue, Apache CXF provides three mechanisms for removing the requirement of using hard coded paths:
Tip
Injecting the proxy into your implementation code is generally the best option.

6.1. Instantiating a Proxy by Injection

Overview

Apache CXF's use of the Spring Framework allows you to avoid the hassle of using the JAX-WS APIs to create service proxies. It allows you to define a client endpoint in a configuration file and then inject a proxy directly into the implementation code. When the runtime instantiates the implementation object, it will also instantiate a proxy for the external service based on the configuration. The implementation is handed a reference to the instantiated proxy.
Because the proxy is instantiated using information in the configuration file, the WSDL location does not need to be hard coded. It can be changed at deployment time. You can also specify that the runtime should search the application's classpath for the WSDL.

Procedure

To inject a proxy for an external service into a service provider's implementation do the following:
  1. Deploy the required WSDL documents in a well known location that all parts of the application can access.
    Tip
    If you are deploying the application as a WAR file, it is recommended that you place all of the WSDL documents and XML Schema documents in the WEB-INF/wsdl folder of the WAR.
    Tip
    If you are deploying the application as a JAR file, it is recommended that you place all of the WSDL documents and XML Schema documents in the META-INF/wsdl folder of the JAR.
  2. Configure a JAX-WS client endpoint for the proxy that is being injected.
  3. Inject the proxy into your service provide using the @Resource annotation.

Configuring the proxy

You configure a JAX-WS client endpoint using the jaxws:client element in you application's configuration file. This tells the runtime to instantiate a org.apache.cxf.jaxws.JaxWsClientProxy object with the specified properties. This object is the proxy that will be injected into the service provider.
At a minimum you need to provide values for the following attributes:
  • id—Specifies the ID used to identify the client to be injected.
  • serviceClass—Specifies the SEI of the service on which the proxy makes requests.

Example 6.1. Configuration for a Proxy to be Injected into a Service Implementation

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:client id="bookClient" 
                serviceClass="org.apache.cxf.demo.BookService"
                wsdlLocation="classpath:books.wsdl"/>
  ...
</beans>
Note
In Example 6.1, “Configuration for a Proxy to be Injected into a Service Implementation” the wsdlLocation attribute instructs the runtime to load the WSDL from the classpath. If books.wsdl in on the classpath, the runtime will be able to find it.
For more information on configuring a JAX-WS client see section "Configuring Consumer Endpoints" in "Configuring Web Service Endpoints".

Coding the provider implementation

You inject the configured proxy into a service implementation as a resource using the @Resource as shown in Example 6.2, “Injecting a Proxy into a Service Implementation”.

Example 6.2. Injecting a Proxy into a Service Implementation

package demo.hw.server;

import org.apache.hello_world_soap_http.Greeter;

@javax.jws.WebService(portName = "SoapPort", serviceName = "SOAPService", 
                      targetNamespace = "http://apache.org/hello_world_soap_http", 
                      endpointInterface = "org.apache.hello_world_soap_http.Greeter")
public class StoreImpl implements Store {

@Resource(name="bookClient")
private BookService proxy;

}
The annotation's name property corresponds to the value of the JAX-WS client's id attribute. The configured proxy is injected into the BookService object declared immediately after the annotation. You can use this object to make invocations on the proxy's external service.