View source | Discuss this page | Page history | Printable version   
Toolbox
Main Page
Upload file
What links here
Recent changes
Help

PDF Books
Add page
Show collection (0 pages)
Collections help

Search

Module:Base Apache CXF Infrastructure/Developers Guide/How To Create And Consume SOAP Web Services

Contents

Introduction

In this document is described the required steps to implement and consume a SOAP web service using the infrastructure provided by the Base Apache CXF Infrastructure module.

This infrastructre is based on Apache CXF, an open source services framework that helps to build different kind of web services.

Bulbgraph.png   When using the Base Apache CXF Infrastructure in environments before the 3.0PR19Q3 release, it is necessary to remove the wsdl4j-1.5.1.jar from the classpath and include the wsdl4j-1.6.3.jar instead. Starting from 3.0PR19Q3 this is not needed.

Example Module

The code shown in this guide is extracted from the Base Apache CXF Infrastructure Examples module which is available in this Mercurial repository.

Creating a SOAP Web Service

When developing a SOAP service it is possible to follow one of two approaches:

The example shown in this guide is based on the Java First Development approach.

SOAP Web Service Components

The first step is to create the components that define the SOAP web service.

Service Endpoint Interface

The definition of the service is done through a Java class called Service Endpoint Interface (SEI). This is the piece of Java code that is shared between a service and the consumers that make requests on it. The methods defined in this class are intended to be mapped to the operations exposed by the service:

 
@WebService
public interface Calculator {
 
  @WebMethod
  public int sum(@WebParam(name = "sum1") @XmlElement(required = true) int sum1,
      @WebParam(name = "sum2") @XmlElement(required = true) int sum2);
 
  @WebMethod
  public int multiply(@WebParam(name = "mul1") @XmlElement(required = true) int mul1,
      @WebParam(name = "mul2") @XmlElement(required = true) int mul2);
}

Note that the SEI makes use of standard JAX-WS annotations to specify the metadata used to map the SEI to a fully specified service definition:

Here it is possible to see detailed information about these annotations and the different properties they accept.

And we are also using an annotation of the JAXB-API to complete the definition of the different parameters of the methods:

Service Implementation Class

The service implementation is a class that will implement two interfaces:

 
@WebService(endpointInterface = "org.openbravo.base.cxf.examples.Calculator", serviceName = "calculatorService", portName = "calculatorServicePort")
public class CalculatorImpl implements Calculator, OBSingleton {
 
  @Override
  public int sum(int sum1, int sum2) {
    return sum1 + sum2;
  }
 
  @Override
  public int multiply(int mul1, int mul2) {
    return mul1 * mul2;
  }
}

In addition to annotating the SEI with the @WebService annotation, the service implementation class is also annotated with the @WebService annotation. When adding the annotation to the service implementation class, the endpointInterface property needs to be specified and it should contain the full class name of the SEI. The rest of the properties are not mandatory.

Publishing the SOAP Web Service

The infrastructure of the Base Apache CXF module provides a mechanism that allows to register and publish automatically the SOAP web services on server startup.

To publish the services, one just need to create a class that implements the SOAPWebServiceRegister interface:

 
public class SOAPExampleWebServiceRegister implements SOAPWebServiceRegister {
 
  @Override
  public List<SOAPWebService<? extends OBSingleton>> getSOAPWebServices() {
    return Arrays
        .asList(SOAPWebService.createSOAPWebService("calculatorService", CalculatorImpl.class));
  }
}

Implement this interface is as simple as implement the getSOAPWebServices() method returning a list of SOAPWebService instances that represents the services to be published.

The SOAPWebService.createSOAPWebService method can be used to create the different SOAPWebService instances. This method receives a String with the name that will be used to publish the service (it will be part of the web service URL) and the Service Implementation Class.

By default, all the services registered as shown above will be automatically secured using basic HTTP Authentication. This security is implemented based on the interceptor mechanism. To know more about interceptors, please refer here.

In case it is desired to disable the basic authentication, implement a custom authentication or just include new incoming interceptors for the service, then it is required to override the default implementation of the getInterceptors() method:

 
public class SOAPExampleWebServiceRegister implements SOAPWebServiceRegister {
 
  @Override
  public List<SOAPWebService<? extends OBSingleton>> getSOAPWebServices() {
    return Arrays
        .asList(SOAPWebService.createSOAPWebService("calculatorService", CalculatorImpl.class));
  }
 
  @Override
  public List<Interceptor<? extends Message>> getInterceptors() {
    // providing a custom interceptor list
    return Arrays.asList(new MyCustomInterceptor());
  }
}

Once we have deployed our SOAPWebServiceRegister, the list of available services can be accessed by default under the following URL:

http://<openbravo_url>/org.openbravo.base.cxf


ListOfSOAPServices.png


And Following our example, we can access to the WSDL definition generated for our service at:

http://<openbravo_url>/org.openbravo.base.cxf/calculatorService?wsdl


Wsdl.png

Creating a SOAP Web Service Consumer

In this section we are going to develop a web service consumer (client) for the SOAP web service created in the first part of this guide.

Generating the Java Stub Code

To develop a consumer the first step is to generate the Java stub code from an WSDL contract. The stub code provides the supporting code that is required to invoke operations on the remote service.

The first step is to retrieve the file containing the WSDL definition and store it in a file of our local computer, for example in /tmp/calculator.wsdl. A best practice for ensuring that we produce a portable client is to package this WSDL document with the sources of our client.

Second, to generate the code of the consumer we can make use of the wsdl2java utility, included in the Apache CXF source distribution that can be downloaded from here.

The command to generate the Java stub code would be as follows:

 ./wsdl2java -keep -wsdlLocation /calculator.wsdl -d /tmp/gen /tmp/calculator.wsdl

Note that we are using the options:

Creating the Consumer

As a result of the code generation done in the previous section we should have an structure for our consumer similar to the following one:


ClientPackageGen.png


We now need to create the implementation of the consumer that performs the calls to the operations exposed by the service:

 
public class SOAPClient {
 
  public static void main(String[] args) {
    // Create the service instance
    CalculatorService service = new CalculatorService();
    Calculator calculator = service.getCalculatorServicePort();
 
    // Set the credentials for the basic HTTP authentication
    BindingProvider bindingProvider = (BindingProvider) calculator;
    Map<String, Object> requestContext = bindingProvider.getRequestContext();
    requestContext.put(BindingProvider.USERNAME_PROPERTY, "user");
    requestContext.put(BindingProvider.PASSWORD_PROPERTY, "pass");
 
    // Print the results
    System.out.println("Sum = " + calculator.sum(1, 2));
    System.out.println("Multiply = " + calculator.multiply(1, 2));
  }
}

The final structure of our client will look like:

ClientPackage.png

Retrieved from "http://wiki.openbravo.com/wiki/Module:Base_Apache_CXF_Infrastructure/Developers_Guide/How_To_Create_And_Consume_SOAP_Web_Services"

This page has been accessed 390 times. This page was last modified on 22 May 2019, at 08:54. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.