Chapter 12. Web Services Reference

Sometimes, in the Business Layer, we must integrate with one or several third party Web Services

12.1. Introduction

In order to deal with this feature, exists the JAX-WS 2.0 specification in order to provide a common way to deal with Web Services integration

12.2. NexOpen and JAX-WS 2.0

NexOpen uses JAX-WS 2.0 in order to integrate with Web Services. Following the nice practices developed by Spring Team, we use AOP and we leave to develoeprs to define properly the interface which provides the gateway to invoke the methods exposed by the foreign Web Service which would like to integrate. Next, we show how to develope the before mentioned ideas, just following the JAX-WS 2.0 specs

	
	....
	import javax.jws.WebMethod;
	import javax.jws.WebParam;
	import javax.jws.WebResult;
	import javax.jws.WebService;
	import javax.jws.soap.SOAPBinding;
	import javax.xml.ws.WebServiceClient;
	import javax.xml.ws.WebServiceRef;
	....
	
	@Business(type=BusinessType.APPLICATION)
    public class MyAppService {   
       
       /***/
       @WebServiceRef(ExampleServiceService.class)
       private ExampleService wsref;
   
       ......
    }
    
    @WebService(targetNamespace = "http://ws.nexopenframework.org/example",
			name="ExampleWS")
    @SOAPBinding(style=SOAPBinding.Style.RPC)
    public interface ExampleService {
	  @WebMethod
	  public String sayHello();
	  @WebMethod
	  @WebResult(name="user")
	  public User findUserByPrimaryKey(@WebParam(name="id") long id) 
	  			throws UserNotFoundException;
    }
    ......
    @WebServiceClient(targetNamespace = "http://ws.nexopenframework.org/example", 
                      name="ExampleWS")
	public class ExampleServiceService extends javax.xml.ws.Service {

      public ExampleServiceService() throws java.net.MalformedURLException {
           super(new java.net.URL("http://my.domain.com/services/ExampleWSService?wsdl"),
                 new javax.xml.namespace.QName("http://ws.nexopenframework.org/example",
                                               "ExampleWSService"));
		}
		
		public ExampleServiceService(java.net.URL wsdlDocumentLocation, 
		                             javax.xml.namespace.QName serviceName) {
			super(wsdlDocumentLocation, serviceName);
		}
		
	}
   .....
	
	

As we can observe, from our Business component, in this case an Application Service, but it is also possible to be defined in a Facade or Configurable Service, we define the needed to integrate with a foreign Web Service

Despite the fact that we write at code level the wsdl URL location, this can be easily changed because NexOpen provides an Standard MBean in order to manage this integration.

12.3. XFire 1.2.x integration

Moreover of the specification annotations and nexOpen custom annotations, in the case of XFire NexOpen provides also the possibility to integrate with common features developed by XFire when client would like to invoke a Web Service

	
.....
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.codehaus.xfire.annotations.EnableMTOM;
import org.codehaus.xfire.annotations.InHandlers;
import org.codehaus.xfire.annotations.OutHandlers;
......
@WebService(targetNamespace = "http://ws.nexopenframework.org/example",
			name="ExampleWS")
@SOAPBinding(style=SOAPBinding.Style.RPC)
@EnableMTOM
@InHandlers(handlers={"org.nexopenframework.example.xfire.DummyHandler"})
@OutHandlers(handlers={"org.nexopenframework.example.xfire.LoggerHandler"})
public interface ExampleService {
 .......
}	
	
	

12.4. Test Support

NexOpen provides support for using JUnit3 as test Framework support. using NexOpen facilities we can easily test if the call related to Web Service is correct or not

	
.....
import org.nexopenframework.core.ws.WebServiceException;
import org.nexopenframework.jaxws.test.xfire.AbstractXFireWebServiceTestCase;
.....
public class ClassificationWSTest extends AbstractXFireWebServiceTestCase {

  /**
   * <p>Here, we initialize our test providing the 
   *    Service Endpoint Interface (SEI) to be tested.</p>
   */
   public ClassificationWSTest() {
      //the service endpoint interface to be tested
      //you must be aware that this interface has JSR-181 annotations
      //Also supports NexOpen WS Reference annotations such as
      //Credentials for BASIC authentication and ProxySettings
      //if you have behind a proxy.
      this.setServiceEndpointInterface(ClassificationWS.class);
      //HTTP wsdl location
      this.setWsdlLocation("http://www.mydomain.com/mycontext/"+
                           "services/ClassificationWSService?wsdl");
	}

	/**
	 * <p>Unique method to be invoked by JUnit3 for
     *   test the ClassificationWS interface. Here, 
     *   you will perform the invocations to publish 
     *   web service methods</p>
	 */
     public void testWebService() throws WebServiceException, IOException {
     
       if (logger.isDebugEnabled()) {
         logger.debug("WSDL location to be tested :: "+ wsdlLocation);
       }
       //retrieve the client to communicate to the external
       //web service
       final Object client = getClient();
       assertNotNull(client);
  	   assertTrue(client instanceof ClassificationWS);
       final ClassificationWS sei = (ClassificationWS) client;
  	   if (logger.isDebugEnabled()) {
           logger.debug("Service Endpoint Interface :: "+ sei);
       }
       //invoke the published methods by external web service
		....
    }  
}
	
	

12.5. Configuration

In case of XFire integration, we must ensure to

Finally, we specify where to place the javax.xml.ws.spi.Provider if you plan to use NexOpen-XFire extension. This file conatins only one line, where we exlicetly specify the NexOpen Provider extension

org.nexopenframework.xfire.jaxws.Provider

In a EAR you must be sure to place at root in a folder META-INF/services as indicate the specs. In a NexOpen-maven2 structure the correct place is

	
+earProject
 |+ear
   |+src
     |+main
       |+resources
         |+META-INF
          |+services
            |+javax.xml.ws.spi.Provider
 .....
	
	

In the case of a WAR artifact you should place into the classpath also in same folder but under WEB-INF/classes location

	
+webProject
 .....
 |+web
   |+src
     |+main
       |+resources
         |+META-INF
          |+services
            |+javax.xml.ws.spi.Provider
 .....