Monday, June 6, 2011

PHP-SOAP web service with out a WSDL

This article is going to describe how to create a simple web service with php-soap step by step.

Requirements

    Server to run php (apache, xampp , wamp)
    PHP-SOAP extension

Steps

Let's write a simple web service to find the length of a given string.

So here is the code for StringLengthServer.php

 <?php
# StringLengthServer.php
# Copyright (c) 2011 by Lakmali Baminiwatta
#

    function findLength($string) {
           return "Length of the string " . $string . "is : ".strlen($string);
    }
      
    $server = new SoapServer(null,
              array('uri' => "urn://www.lakmali.lk"));
  
    $server->addFunction("findLength");
       $server->handle(); 

?>

  • First thing done here is to write a function to perform the action done by the service. So here function findLength($string) takes a string as the argument and prints back the length of it.
  • Then SoapServer is created. First argument null which means no WSDL used. Second argument is uri value is just a unique string as the namespace.
  • Then we have to add the function findLength to the server.
  • Now copy the file StringLengthServer.php to the server to run. Here it is assumed the url which service run is http://localhost/simple_server/StringLengthServer.php.
  • Now let's write a simple client program to get the service from the webservice.

    So here is the code for StringLengthClient.php
<?php
 StringLengthClient.php
# Copyright (c) 2011 by Lakmali Baminiwatta
#
   $client = new SoapClient(null, array(
      'location' => "http://localhost/simple_server/StringLengthServer.php",
      'uri'      => "urn:urn://www.lakmali.lk",
      'trace'    => 1 ));

   $return = $client->__soapCall("findLength",array("lakmali"));
   echo("\nReturning value of __soapCall() call: ".$return);

   echo("\nDumping request headers:\n"
      .$client->__getLastRequestHeaders());

   echo("\nDumping request:\n".$client->__getLastRequest());

   echo("\nDumping response headers:\n"
      .$client->__getLastResponseHeaders());

   echo("\nDumping response:\n".$client->__getLastResponse());
?>

In here the location argument of the SoapClient must be the URL to server program which we wrote above and added to run. Make sure it is correct.

Run this StringLengthClient.php to receive the service.

So the output will be:

Returning value of __soapCall() call: Length of the string lakmali is : 7
Dumping request headers:
POST /simple_server/StringLengthServer.php HTTP/1.1
Host: localhost
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.2.9
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:urn://www.lakmali.lk#findLength"
Content-Length: 510

Dumping request:



 lakmali


Dumping response headers:
HTTP/1.1 200 OK
Date: Tue, 07 Jun 2011 13:24:06 GMT
Server: Apache/2.2.10 (Fedora)
X-Powered-By: PHP/5.2.9
Content-Length: 550
Connection: close
Content-Type: text/xml; charset=utf-8

Dumping response:



 Length of the string lakmali is : 7

Here the client program is written to display SOAP messages exchanged. But for a real client ony you need is return value from soapCall.


<?php
# StringLengthClient.php
# Copyright (c) 2011 by Lakmali Baminiwatta
#
   $client = new SoapClient(null, array(
      'location' => "http://localhost/simple_server/StringLengthServer.php",
      'uri'      => "urn:urn://www.lakmali.lk",
      'trace'    => 1 ));

   $return = $client->__soapCall("findLength",array("lakmali"));
   echo("\nResult: ".$return);
?>

Thursday, June 2, 2011

Java Initialization order

When a java class get loaded first all the static fields will be loaded with their default values.
Then static inits of the class begins in order, which means static fields will be initialized as given in order.


  • So in the given example code line 1 will load the class LakmaliClass with all its static fields assigning to default values.
  • Then static inits will begin executing line 5, 6 and 7.
  • Then instance inits will begin executing line 2, 3 and 4.
  • Line 2 will load the class Second with all the static fields default values (Here no static fields)
  • Then object will be created with passed values.
  • Line 3 will also do the same.


class Initializer{

    public static void main(String args[]){
        LakmaliClass o=new LakmaliClass(); // line 1
      
    }

}

class LakmaliClass{


    {
        System.out.println("Lakmali class instance init"); //line 2
        Second s1=new Second(s);            //line 3
        Second s2=new Second(number1);            //line4
    }

    static String text1="text1"; //line 5
    static int number1=1;        //line 6

    static{
        System.out.println("Lakmali class static init");    //line 7
    }
}

class Second{

    Second(String s){
        System.out.println(s);

    }

    Second(int i){
        System.out.println(i);
    }


}


result: 

Lakmali class static init
Lakmali class instance init
text1
1


Let's see a different example, where instance will be created in static init.

class Initializer{

    public static void main(String args[]){
        LakmaliClass.getInstance(); // line 1
       
    }

}

class LakmaliClass{

    {
        System.out.println("Lakmali class instance init"); //line 2
        Second s=new Second(text1,number1);            //line3
    }

    static LakmaliClass o=new LakmaliClass();            //line 4

    static String text1="text1"; //line 5
    static int number1=1;        //line 6
   
    static{
        System.out.println("Lakmali class static init");    //line 7
    }

    static LakmaliClass getInstance(){
        return o;
    }
}

class Second{

    Second(String s, int i){
        System.out.println("value1: "+s+"\nvalue2: "+i);
    }


}


result:

Lakmali class instance init
value1: null
value2: 0
Lakmali class static init


Here you can see that instance inits had run before static init. It happend in this order.

  • line 1 load class LakmaliClass with all its static fields default values.
  • Static inits begin.
  • First line 4 runs. It creates an instance of LakmaliClass. So instance init of LakmaliClass will be executed with current values. So text1 or number1 fields are not initialized to given values as line 5 and 6 have not executed yet. So text1 and number1 will have their default values.
  • Now line 5, line 6 and line 7 will execute in order.
  • Then getInstance method will be invoked.