Friday, October 8, 2010

A simple tutorial about creating Zend Framework SOAP Web service server in Zend Studio 7.2

I was studying how to create Web Service in PHP recently. I used Axis1.0, Axis2.0 to create Web service before. I used NuSoap to make a web service to call Sync4J admin service too. I like Axis' wsdl2java and java2wsdl tool set very much. In PHP, there is similar tool too. However, this time, I decide to implemented Web service under Zend Framework. After trying, I found it is quiet easy to create a simple Web service in ZF although I found that Zend_Soap_Server is not sophisticated enough to make solution for Enterprise application. For example, it does not have build in support for WS security head. It is actually a wrapper around PHP Soap extension. You can find discussion from Zend wiki by click here.

I will show steps of creating ZF based Web Service in Zend studio as below. Also, I put download link of whole ZS project at the end. We can create this simple demo project as below,
  1. Create a new ZF project in Zend Studio and name it as jiaWS.
  2. Add autoloaderNamespaces[] = "Jia_" in application.ini to allow Zend Autoloader load Jia_* classes.
  3. Creating a action class DummyController under directory /application/controllers. 
  4. creating a function soapAction() in DummyController .
  5. creating a function wsdlAction() in DummyController. 
  6. Creating a Jia_Hello class with sayHello() function under /library/Jia directory.
  7. Creating a Jia_DummyException class under /library/Jia directory for Soap fault processing.
It is done! You need to pay attention on how to specify web service URI in the code if you use different project name and function names. See key source code as below,

Jia_Hello class.
/**
 * This class contains function which will be used by Web service caller.
 * All business logics will be implented or called in these functions.
 * 
 * @author Yiyu Jia
 *
 */
class Jia_Hello {

 /**
  * This function simply return a String when it is called.
  * Note :  the PHPDoc style comment below is very 
  * important as Zend_Soap_AutoDiscover use it to generate WSDL. 
  * 
  * @return string
  */
 public function sayHello(){
  return "hello";
 }
}

DummyController calss
/**
 * This class includes two functions. soapAction() is point called by
 * Web service client. wsdlAction() generates WSDL when it is called.
 * 
 * @author yiyu
 *
 */
class DummyController extends Zend_Controller_Action
{
 /**
  * SOAP action named as soap.
  */
 public function soapAction() {
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initialize server and set URI
  $server = new Zend_Soap_Server('http://localhost/jiaWS/public/index.php/dummy/wsdl');
  
  // set SOAP service class
  $server->setClass ( 'Jia_Hello' );
  
  // register exceptions for generating SOAP faults
  $server->registerFaultException ( array ('Jia_DummyException' ) );
  
  // handle request
  $server->handle ();
 
 }
 /**
  * function to generate WSDL.
  */
 public function wsdlAction() {
  
  //You can add Zend_Auth code here if you do not want 
  //everybody can access the WSDL file.
 
  // disable layouts and renderers
  $this->getHelper ( 'viewRenderer' )->setNoRender ( true );
  
  // initilizing zend autodiscover object.
  $wsdl = new Zend_Soap_AutoDiscover ();
  
  // register SOAP service class
  $wsdl->setClass ( 'Jia_Hello' );
  
  // set a SOAP action URI. here, SOAP action is 'soap' as defined above.
  $wsdl->setUri ( 'http://localhost/jiaWS/public/index.php/dummy/soap' );
  
  // handle request
  $wsdl->handle ();
 }

}


DummyClient.php
//This code is not a ZF MVC based
//So, we need to load Zend libraries
require_once 'Zend/Loader.php';
Zend_Loader::loadClass ( 'Zend_Soap_Client' );

//setting options past into Zend_Soap_Client.
$options = array ('location' => 'http://localhost/jiaWS/public/index.php/dummy/soap', 'uri' => 'http://localhost/jiaWS/public/index.php/dummy/wsdl' );

try {
 //Initilizing client object
 $client = new Zend_Soap_Client ( null, $options );
 //calling the Web service function.  
 $result = $client->sayHello ();
 print_r ( $result );
} catch ( SoapFault $exp ) { //catching exception and print out.
 die ( 'ERROR: [' . $exp->faultcode . '] ' . $exp->faultstring );
} catch ( Exception $exp2 ) {
 die ( 'ERROR: ' . $exp2->getMessage () );
}

Source code as Zend Studio project can be downloaded click here

You can find a simple RESTful Web Service demo on my another post, creating RESTful service with Zend_Rest_Route and Zend_Rest_Controller.

7 comments:

  1. when i run your sample on localhost this error occurs(after a long time):
    ERROR: [HTTP] Error Fetching http headers
    but it works on a real host.
    My own Web Service i wrote have the same problem.
    how can i solve it?

    ReplyDelete
  2. I never see this error. I feel it is your local machine's configuration problem.

    ReplyDelete
  3. i m getting this error :
    ERROR: [Sender] looks like we got no XML document

    ReplyDelete
  4. I feel that your server side configuration has problem if you use exactly my original code. Did you configure the URI rewrite engine properly?

    BTW, I do not think PHP SOAP WS is a sophisticated solution for SOAP based WS solution. PHP is probably more suitable for creating RESTful WS. So, you can use Java to create SOAP WS if you have choice.

    ReplyDelete
  5. Here is a tutorial about how to create a Metro (JAX-WS) Web service in Netbeans 6.9.1 .

    http://yiyujia.blogspot.com/2011/02/simple-tutorial-about-creating-metro.html

    Using Java to create SOAP based Web service if you can.

    ReplyDelete
  6. Hi Thanks for your tutorial , I’ve just downloaded the code and try to run it on my local host but nothing comes up,
    would you please help me to sort it out

    ReplyDelete
  7. This XML file does not appear to have any style information associated with it. The document tree is shown below.

    ReplyDelete