The Web at your (machine’s) service

Use Web services to deliver information to a cell phone via SMS

The World Wide Web changes constantly. Since its inception, it has expanded exponentially, grown easier to navigate, and adapted effortlessly to new and innovative uses. However, thus far the Web’s interface has been largely friendly to humans but unfriendly to machines.

Current technologies open up the Web only to humans through HTML links and URLs. Just imagine the services we could provide if machines could suddenly discover, traverse, and navigate the myriad of Web servers to facilitate true wide-area collaboration. Current approaches prove somewhat awkward: a common technique screen-scrapes HTML and mimics HTTP sessions to transfer data. Techniques such as these are not only incomplete (e.g., they lack a discovery mechanism) and unscalable (e.g., if one field on an HTML form changes, the whole interface can crash, so each server needs its own custom coding); they also prove difficult to maintain. Web services, on the other hand, provide a well-defined discovery and communication framework based on XML and HTTP that facilitates interaction between machines; they offer true peer-to-peer distributed computing over the Web. The advent of Web services has made the World Wide Web truly complete; they provide the missing link — a machine-friendly user interface (UI) to the Web.

Admittedly, these concepts are not entirely new; distributed object-oriented technologies like CORBA and Remote Method Invocation (RMI) sought to provide similar services. Such core concepts as a service registry and TCP/IP-based communication protocol are common to both CORBA (registry/agent and Internet Inter-ORB Protocol (IIOP)) and Web services (UDDI and SOAP). But CORBA failed because it proved quite complicated and expensive to implement — both in terms of cost and performance. Furthermore, the object bus could not create a genuine heterogeneous environment consisting of multiple hardware and software platforms. Web services, on the other hand, rely on ubiquitous technologies like XML and HTTP, and thus stand a fighting chance of being that ultimate Web glue.

This article develops a clearer understanding of Web services and illustrates a hands-on approach to developing an example service. We use our CellQuotes application presented in “Deliver Cellular Text Messages with SMS” (JavaWorld, March 2001) and demonstrate how to publish it as a Web service. Many expect SMS to be the next killer app for mobile phones; if Web services can provide a seamless coupling between the Web and mobile phones, we’ll have an application that rocks, don’t you think?

Web services 101

Web services offer the following advantages:

  • They are based on open and ubiquitous standards: Web services use omnipresent protocols such as HTTP for communication and XML for information exchange. Thus, they can work across hardware and software boundaries. For example, a Java Web service could easily talk to a COBOL Web service as long as HTTP and XML are in the mix.
  • They allow creation of business service stacks: By simply adding another layer, Web services expose software systems over the Internet. That allows the creation of value-added service stacks by melding discrete Web services over a network.
  • They enjoy broad-based industry support: Efforts like Microsoft’s Hailstorm and Sun’s ONE (Open Net Environment) are slowly turning Web services into a reality. IBM and Oracle are also major players in the Web services space. In addition, the open source movement’s solid support ensures widespread developer interest.

Web services’ greatest potential lies in their ability to provide business service stacks that truly integrate individual offerings. Imagine writing your own Web service agent that every morning collects and delivers information relevant to you (e.g., the HP-Compaq merger) from resources like the Wall Street Journal, the Economist, and BusinessWeek. Similar services exist today, but Web services help standardize machine-to-machine interaction to create new service breeds that integrate the Web as one large computer. On the supply side, you could publish your revolutionary service to millions of people worldwide without worrying about custom coding and interoperability issues.

Core enabling technologies

Several new technologies support Web services, but because they build on pre-existing technologies like XML and HTTP, they’re not as new as you might think. Lets briefly look at some:

SOAP (Simple Object Access Protocol)

SOAP is the transport that facilitates the exchange of XML messages between machines. It performs business method requests as XML documents and supports a variety of lower-level protocols, such as HTTP(S) and SMTP (Simple Mail Transfer Protocol). The communication mechanism consists of request and response XML documents that have an envelope over them.

WSDL (Web Services Description Language)

An XML language that permits standardized description of Web services, WSDL describes the interface, semantics, and administration-related information of a Web service call. It allows simple services to be quickly and easily described, documented, and discovered. Several freely available tools permit automatic WSDL generation from actual code (such as a Java class), thus making the developer’s job easier.

UDDI (Universal Description Discovery and Integration)

UDDI provides a specification that permits the publication and location of services in a universal service registry. It publishes an available service along with its call interface and semantics, thereby providing a discovery and meeting point for service providers and consumers. The UDDI specification defines four key types of information that might be needed to facilitate service use:

  1. Business information (businessEntity element): Contains information such as the business name, contact details, and so on. It might also include information categorized in a way similar to the format of the Yellow Pages.
  2. Service information (businessService element): Contains information about services relevant to a particular business function or a given service category. Each businessEntity might hold several businessServices.
  3. Binding information (bindingTemplate element): Contains information required to call a Web service, such as network access point, supported interfaces, and so on. Each businessService might hold several bindingTemplates.
  4. Specification information (tModels): To invoke a Web service, you must know a service’s location and the kind of interface the service supports. The bindingTemplate indicates the specifications or interfaces a service supports through references to specification information. Such a reference is called a tModelKey, and the data structure encapsulating the specification information is called a tModel. tModels are reusable due to their use of references.

Figure 1 illustrates the relationship between the different components explained above.

Figure 1. UDDI data structures and their relationships. Click on thumbnail to view full-size image.

WSDL and UDDI

WSDL and UDDI together provide a powerful mechanism for the automatic description, discovery, and integration of Web services. UDDI features a universal registry that can hold any information about a Web service. Different people might use this information for different purposes. For example, a developer could use the registry to obtain the technical information required to build her own service and/or consume an existing service. A market researcher could use it to understand what services are most in demand. WSDL enables the uniform description of a Web service in an open manner — it is UDDI’s lingua franca. Thus, when used together, UDDI (which provides global visibility and accessibility) and WSDL (which provides standardized and portable service descriptions) pack quite a punch. Usually, developers use WSDL to describe Web services’ semantics, such as method signatures, return types, and so on, in an implementation-independent way. This WSDL description is then embedded in the service’s UDDI entry (usually through tModels) along with the information needed to actually call that service (through bindingTemplates).

The process for using a Web service consists of discovery, connection, and consumption. We outline the steps here in greater detail:

  1. A service provider creates a Web service and uses WSDL to publish the service in the UDDI registry.
  2. A service consumer locates and requests the registered service by querying the UDDI registry.
  3. Using SOAP, the service consumer writes an application to bind to the registered service and establishes a communication channel. The WSDL description provides the method signatures.

Figure 2 illustrates the steps outlined above.

Figure 2. Web services: Discovery to consumption. Click on thumbnail to view full-size image.

SMS Web service

Now, let’s get back to the nitty-gritty of developing a real-world Web service — namely, a service that sends text messages to cellular phones. To this end, we will convert the CellQuotes application presented in “Deliver Cellular Text Messages with SMS” into an application that exploits Web services. For the benefit of those unfamiliar with the application, a brief recap follows.

The CellQuotes system periodically sends stock quotes to a user’s cell phone using Short Message Service (SMS). The user provides the stocks for which she wants quotes as well as cellular details, such as provider and number. Here are some of the solution’s classes:

  • CellProvider.java: The interface that must be implemented to add cellular service providers
  • CellProviderSelector.java: The factory that returns the appropriate CellProvider implementation based on the user’s inputs
  • USCellOne.java: CellProvider‘s concrete implementation for the Cellular One service provider

We want to expose the USCellOne.java implementation as a Web service and suitably modify the application so that it can send SMS messages. Figure 3 shows the major components and their interaction. The blue squares represent servers.

Figure 3. Create a CellQuotes Web service. Click on thumbnail to view full-size image.

We use the following software for developing the Web service:

  1. IBM UDDI4J API
  2. IBM UDDI Test Registry
  3. Apache SOAP
  4. Apache Tomcat

To develop the Web service, we follow these steps:

  1. Generate a WSDL document for the CellProvider interface
  2. Publish the WSDL description as a tModel
  3. Expose the USCellOne implementation as a Web service, deployed on Apache Tomcat
  4. Publish information about this implementation as a businessService

Generate WSDL document

We used the template provided in the WSDL and UDDI best practices document and changed it to create a description of our CellProvider interface. You can also use tools, like the Web Services Description Language for Java Toolkit (WSDL4J) or CapeStudio from Cape Clear, to generate the WSDL.

The CellProvider WSDL description is listed below. While a detailed explanation of the document reaches beyond this article’s scope, if you have a basic familiarity with XML, you should be able to follow it. For further information, please read the WSDL spec in Resources.

<?xml version="1.0"?>
<definitions name="CellText"
   targetNamespace="
interface.wsdl"
   xmlns:tns="interface.wsdl"
   xmlns:soap="
   xmlns="
   xmlns:xsd="
 <message name="getName_IN"/>
 <message name="getName_OUT">
   <part name="Result" type="xsd:string"/>
 </message>
 <message name="sendMessage_IN">
   <part name="number" type="xsd:string"/>
   <part name="message" type="xsd:string"/>
 </message>
 <message name="sendMessage_OUT">
   <part name="Result" type="xsd:boolean"/>
 </message>
 <message name="isMe_IN">
   <part name="id" type="xsd:string"/>
 </message>
 <message name="isMe_OUT">
   <part name="Result" type="xsd:boolean"/>
 </message>
 <portType name="CellTextPortType">
   <operation name="getName">
    <documentation>Returns User-friendly Provider name</documentation>
    <input message="tns:getName_IN"/>
    <output message="tns:getName_OUT"/>
   </operation>
   <operation name="sendMessage" parameterOrder="number message">
    <documentation>Sends a text message to specified number</documentation>
    <input message="tns:sendMessage_IN"/>
    <output message="tns:sendMessage_OUT"/>
   </operation>
   <operation name="isMe">
    <documentation>Checks whether the implementation is for specified ID</documentation>
    <input message="tns:isMe_IN"/>
    <output message="tns:isMe_OUT"/>
   </operation>
 </portType>
 <binding name="CellTextSoapBinding" type="tns:CellTextPortType">
   <soap:binding style="rpc" 
    transport="
   <operation name="getName">
    <soap:operation soapAction="urn:celltext-service"/>
    <input>
    <soap:body use="encoded" namespace="urn:celltext-service"
      encodingStyle= "
    </input>
    <output>
    <soap:body use="encoded" namespace="urn:celltext-service"
     encodingStyle="
    </output>
   </operation>
   <operation name="sendMessage">
    <soap:operation soapAction="urn:celltext-service"/>
    <input>
    <soap:body use="encoded" namespace="urn:celltext-service"
     encodingStyle="
    </input>
    <output>
    <soap:body namespace="urn:celltext-service" use="encoded"
      encodingStyle="
    </ouput>
   </operation>
   <operation name="isMe">
    <soap:operation soapAction="urn:celltext-service"/>
    <input>
    <soap:body use="encoded" namespace="urn:celltext-service"
      encodingStyle="
    </input>
    <output>
    <soap:body use="encoded" namespace="urn:celltext-service"
      encodingStyle="
    </output>
   </operation>
 </binding>
</definitions>

Publish the WSDL description

Next, we need to publish the CellProvider WSDL document to a UDDI registry. To do that, we use the IBM UDDI Test Registry. First, set up a free account at the IBM UDDI Test Registry Website. Then use the registry’s Web interface to manually add the tModel for this interface specification. (You can also do this programmatically.)

Expose the Web service

Contrary to popular perception, exposing the Web service is the easiest part of the process (at least with Apache SOAP). You only need to ensure that the USCellOne class is accessible via the CLASSPATH. Assuming that you are using Tomcat with Apache SOAP, simply point the browser to and use the Web interface to deploy the service.

Apache SOAP requires the following basic information to establish a communication channel:

  1. ID: The service uniform resource name (URN) that identifies the Web service
  2. Methods: The list of exposed methods
  3. Class: The class name containing method implementations (of exposed method(s))

In addition to the requirements above, other options are available. As the Apache SOAP documentation provides a full-fledged user’s guide devoted to those options, we skip the details here.

Once the service deploys, you can call your service’s methods with a SOAP request to /servlet/rpcrouter along with the URN assigned to your service.

Publish the Web service

To facilitate the automatic discovery and correct use of our service, we need to not only publish the router URL and service URN, but also indicate CellProvider interface’s implementation. Additionally, for the purpose of our CellQuotes application, we need to designate the cellular service providers to which our service can send text messages. We assume that cell phone users subscribing to a particular cellular service provider have a common prefix in their cell phone numbers when represented in the International Dialing Format. For example, Cellular Provider A’s subscribers might have numbers of the form 001-123-456-xxxx, while Cellular Provider B’s subscribers could have numbers of the form 001-123-789-xxxx. Our Web service publishes a number prefix list to indicate the cellular providers to which it can send messages. Thus, in the above example, if this list includes 001-123-456, our service can send text messages to all of Cellular Provider A’s subscribers.

While this approach proves less than perfect, it suffices for this exercise. However, we would love to learn of any other approaches you might care to present.

To publish a service to a UDDI registry, a businessEntity must already exist. Assuming one already does, the following code illustrates how to publish a Web service:

public class SaveCellTextService
{
 public static void main (String args[])
 {
   // Publishing requires HTTPS to ensure security
   // The following lines set up the environment to use HTTPS
   // using JSSE
   System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
   java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
   // The proxy acts as a front to all registry operations
   UDDIProxy proxy = new UDDIProxy();
   try
   {
    proxy.setInquiryURL("
    proxy.setPublishURL("
    // The credentials
    AuthToken token = proxy.get_authToken("userid", "password");
    /*********************************************
    Various data structures that hold all the information
    for a Web service. */
    Vector tModelInstanceInfosVector, businessServicesVector;
    Vector bindingTemplatesVector;
    TModelInstanceDetails tModelInstanceDetails;
    TModelInstanceInfo interfaceTModel, providerTModel;
    InstanceDetails providerDetails;
    InstanceParms providerParams;
    BindingTemplates bindingTemplates;
    BindingTemplate bindingTemplate;
    AccessPoint accessPoint;
    BusinessServices businessServices;
    BusinessService businessService;
    /***********************************************/
    // Indicate that this service implements CellProvider interface
    // by referencing tModel using tModelKey
    interfaceTModel = new TModelInstanceInfo("UUID:15DE8C40-991F-11D5-BA0D-0004AC49CC1E");
    /**********************************************
    Indicate that this service supports the number
    prefix mechanism of identifying cellular providers,
    and also pass in the list of supported providers */
    providerTModel = new TModelInstanceInfo("UUID:80177E70-97F6-11D5-8471-0004AC49CC1E");
    providerParams = new InstanceParms("001240271");
    providerDetails = new InstanceDetails();
    providerDetails.setInstanceParms(providerParams);
    providerTModel.setInstanceDetails(providerDetails);
    tModelInstanceInfosVector = new Vector();
    tModelInstanceInfosVector.addElement(interfaceTModel);
    tModelInstanceInfosVector.addElement(providerTModel);
    /***********************************************/
    tModelInstanceDetails = new TModelInstanceDetails();
    tModelInstanceDetails.setTModelInstanceInfoVector(tModelInstanceInfosVector);
    /**********************************************
    Publish location of Web service and service URN */
    bindingTemplate = new BindingTemplate("", tModelInstanceDetails);
    accessPoint = new AccessPoint("
rpcrouter#urn:celltext:cingular","http");
    bindingTemplate.setAccessPoint(accessPoint);
    bindingTemplatesVector = new Vector();
    bindingTemplatesVector.addElement(bindingTemplate);
    bindingTemplates = new BindingTemplates();
    bindingTemplates.setBindingTemplateVector(bindingTemplatesVector);
    /************************************************/
    // This is the top-level businessService structure
    // The business key identifies the service producer
    businessService = new BusinessService("","Cingular Wireless Washington (US) CellText Service",bindingTemplates);
    businessService.setBusinessKey("BLAH-BLAH");
    businessServicesVector = new Vector();
    businessServicesVector.addElement(businessService);
    // Perform actual publishing to registry
    proxy.save_service(token.getAuthInfoString(),businessServicesVector);
   }
   catch(Exception e)
   {
     e.printStackTrace();
   }
 }
}

The above code simply creates a businessService object populated with all the data we want to publish and then publishes the service to the registry. Again, an explanation of all businessService‘s data structures reaches beyond this article’s scope. See the various UDDI specifications in Resources for more information.

Voilà! Our Web service is now exposed to the whole wide world.

Consume Web services

To send SMS messages through this Web service, we need to consume the service. To do that, we retrofit our CellQuotes application to dynamically discover and connect to this Web service, which meets our interface specifications.

We first write a default local implementation of CellProvider, which uses SOAP to perform remote procedure calls (RPCs) on a deployed service. Note that this default implementation is required only because we are retrofitting an existing application; otherwise, the SOAP-RPC code could directly integrate with the application. This default implementation assumes that the called services are implementations of the CellProvider interface. The constructor requires only the router URL and service URN. The following code illustrates the default implementation:

public class ApacheSOAPCellProviderServiceTalker implements CellProvider
{
 private URL accessPointURL;
 private String soapAction;
 /* Constructor requires the URL of the SOAP RPC Router, and the URN of the
   target Web service. It is assumed that the target service implements the
   CellProvider interface.
 */
 public ApacheSOAPCellProviderServiceTalker(String accessPointURL, String soapAction) throws MalformedURLException
 {
   this.accessPointURL = new URL(accessPointURL);
   this.soapAction = soapAction;
 }
 /* Sends a text message to specified cell number
  */
 public boolean sendMessage(String number,String message) throws Exception
 {
   // Prepare the invocation
   Call call = new Call();
   call.setTargetObjectURI(soapAction);
   call.setMethodName( "sendMessage" );
   call.setEncodingStyleURI( Constants.NS_URI_SOAP_ENC );
   Vector params = new Vector();
   params.addElement( new Parameter( "number", String.class, 
number, null ) );
   params.addElement( new Parameter( "message", String.class, message,
 null ) );
   call.setParams( params );
   try
   {
     // Perform RPC
     Response response = call.invoke(accessPointURL,"");
     // Has an error occurred ?
     if(response.generatedFault())
     {
       Fault f = response.getFault();
       System.err.println( "Could not complete RPC. Fault=" 
+ f.getFaultCode() + ", " + f.getFaultString());
       return(false);
     }
     // All OK, get result
     Boolean result = (Boolean) response.getReturnValue().getValue();
     return(result.booleanValue());
   }
   catch( SOAPException e )
   {
     // Uh-Oh
     e.printStackTrace();
     return(false);
   }
  }
 ...
}

Thus, the default implementation acts as a proxy for the remote service.

Next, we need to modify our CellProviderSelector so it can talk to a UDDI registry and obtain the list of services that implement our CellProvider interface. Once the list is obtained, the CellProviderSelector must determine which of these services can send messages to the target cell phone number. To do that, it uses the number prefix.

The presented application can consume the registered Web service only if the Web service implements our CellProvider interface and supports the number prefix provider-identification mechanism. Thus, a UDDI registry service complies with our specification if it references the two registered tModels (one for the CellProvider interface and the other for cellular provider identification). In UDDI-speak, a collection of tModelKeys used while searching the registry is called a tModelBag. It represents a technical fingerprint for our desired service. Our CellProviderSelector uses the following algorithm to obtain the list of compliant services:

  1. Obtain a list of all businesses that provide services matching our tModelBag
  2. For each of these businesses, get the list of services that match our tModelBag
    1. For each service, obtain further details from the registry, such as the binding information, supported cellular providers list, and so on
    2. Using the obtained details, determine if the service matches our target cell phone number
      1. If yes, create an instance of our local CellProvider proxy, passing in the requisite binding information
      2. Otherwise, continue the search

The following code illustrates this algorithm in action:

public abstract class CellProviderSelector
{
 /* Returns appropriate CellProvider implementation for specified ID.
  * Null if none was found.
  */
 public static CellProvider getProvider(String ID)
 {
   try
   {
    // The registry proxy
    UDDIProxy proxy = new UDDIProxy();
    proxy.setInquiryURL("
    /*******************************************
    Setup the tModelBag */
    Vector tModelKeyStringsVector = new Vector();
    TModelBag tModelBag;
    tModelKeyStringsVector.addElement("UUID:15DE8C40-991F-11D5-BA0D-0004AC49CC1E");
    tModelKeyStringsVector.addElement("UUID:80177E70-97F6-11D5-8471-0004AC49CC1E");
    tModelBag = new TModelBag(tModelKeyStringsVector);
    /*********************************************/
    // Get list of businesses
    BusinessList bl = proxy.find_business(tModelBag,null,10);
    Vector businessInfoVector = ((BusinessInfos) bl.getBusinessInfos()).getBusinessInfoVector();
    System.out.println("nNumber of businesses providing CellText services = " + businessInfoVector.size());
    // For each business, get list of compliant services
    for(int i=0; i < businessInfoVector.size(); i++)
    {
      System.out.println("nCurrent Business = " + ((BusinessInfo) businessInfoVector.elementAt(i)).getNameString());
      ServiceList sl = proxy.find_service(((BusinessInfo) businessInfoVector.elementAt(i)).getBusinessKey(),tModelBag,null,10);
      Vector serviceInfoVector = sl.getServiceInfos().getServiceInfoVector();
      System.out.println("tNo. of CellText services = " + serviceInfoVector.size());
      // Get details for each compliant service
      for(int j=0; j<serviceInfoVector.size(); j++)
      {
       ServiceDetail sd = proxy.get_serviceDetail(((ServiceInfo) serviceInfoVector.elementAt(j)).getServiceKey());
       Vector businessServiceVector = sd.getBusinessServiceVector();
       for(int k=0; k<businessServiceVector.size(); k++)
       {
         BusinessService bs = (BusinessService) businessServiceVector.elementAt(k);
         System.out.println("ttService Name = " + bs.getNameString());
         Vector bindingTemplateVector = ((BindingTemplates) bs.getBindingTemplates()).getBindingTemplateVector();
         // Determine if the service is appropriate
         for(int l=0; l<bindingTemplateVector.size(); l++)
         {
           BindingTemplate bt = (BindingTemplate) bindingTemplateVector.elementAt(l);
           AccessPoint ap = (AccessPoint) bt.getAccessPoint();
            // Verify the service uses our chosen transport
            if(!"http".equalsIgnoreCase(ap.getURLType()))
            {
              continue;
            }
            System.out.println("ttAccess Point = " + ((AccessPoint) bt.getAccessPoint()).getText());
            Vector tModIIV = ((TModelInstanceDetails) bt.getTModelInstanceDetails()).getTModelInstanceInfoVector();
            for(int m=0; m<tModIIV.size(); m++)
            {
              if("UUID:80177E70-97F6-11D5-8471-0004AC49CC1E".equalsIgnoreCase(((TModelInstanceInfo) tModIIV.elementAt(m)).getTModelKey()))
              {
               InstanceDetails id = ((TModelInstanceInfo) tModIIV.elementAt(m)).getInstanceDetails();
               InstanceParms ip = id.getInstanceParms();
               System.out.println("ttSupported Prefixes = " + ip.getText());
               // Check if this service can serve our target cell phone number
               if(isSuitableService(ip.getText(),ID))
               {
                 // Create instance of local CellProvider proxy
                 return(createCellProvider(ap.getText()));
                }
             }
           }
         }
       }
     }
   }
   return(null);
   }
   catch(Exception e)
   {
     e.printStackTrace();
     return(null);
    }
 }
 /* Creates local CellProvider proxy instance
  */
 private static CellProvider createCellProvider(String accessPoint)
 {
   if(accessPoint == null || accessPoint.indexOf("#") == -1)
     return(null);
   try
   {
    String router = accessPoint.substring(0,accessPoint.indexOf("#"));
    String urn = accessPoint.substring(accessPoint.indexOf("#")+1);
    CellProvider cp = new ApacheSOAPCellProviderServiceTalker(router,urn);
    return(cp);
   }
   catch(Exception e)
   {
     e.printStackTrace();
     return(null);
   }
 }
 /* Checks whether a service can serve our target cell phone
  */
 private static boolean isSuitableService(String csvVals, String id)
 {
   StringTokenizer st = new StringTokenizer(csvVals, " ,:");
   String token;
   while(st.hasMoreTokens())
   {
     token = st.nextToken().trim();
     if(id.startsWith(token))
     {
       return(true);
     }
   }
   return(false);
 }
}

As evident from the code above, getting to a service’s inner details is slightly tedious. Also, it is sometimes inconvenient to first obtain the list of businesses that provide compliant services, then cycle through each business, and so on. Why not allow access to compliant services directly? Well, enter into the UDDI programmer’s world — that’s just the way the UDDI API is designed right now!

Limitations

Although UDDI and WSDL represent a significant step toward facilitating the automatic discovery and consumption of dynamic Web services, they leave several questions unanswered, and there are areas for improvement. In our example, we can automatically interact only with services known to implement our CellProvider interface. Could we have a system that looks for remote services to invoke based only on a general purpose? In our example, for instance, the service would not necessarily look for the CellProvider interface, but would rather search for services that sent cellular text messages.

There are other gray areas associated with Web services:

  • How should a service producer charge for a service?
  • How do you implement consumer-level security?
  • How do you provide distributed transaction semantics?

The absence of a standardized system that addresses these and other concerns hampers the tremendous potential of Web services.

Web services are here to stay

In this article, we converted an existing Java application into a Web service and exposed it to a global audience. We showed how to use UDDI and WSDL to facilitate optimal use of Web services. In addition, we demonstrated how UDDI makes possible the dynamic discovery and consumption of global services. We also illustrated how to modify an existing application client into one that can consume Web services.

Web services maximize business goals by producing smart applications that dynamically discover the best ways to perform business functions. They represent the next leap in distributed object-oriented computing and are certainly here to stay. Although Web services feature some limitations, as the technology grows and matures, those issues will eventually resolve themselves.

Sonal Bansal is currently
in the computer science program at Loyola College, India. He
has almost five years of programming experience, having completed
work for organizations like Tata Consultancy Services, IRIEEN
(Indian Railway Institute of Electrical Engineering), and Southern
Railway. He has become a devout Java’er after rummaging through C
and other languages.

Gaurav Pal is an
associate project manager with RDA, a custom software
solutions firm. He has a BS in computer science with more than
seven years of software development experience, including over four
years in Java. He is also a Sun-certified developer for the Java 2
Platform and a Java 2 and Java 1.1 programmer. Currently, he is
working towards his MBA at the Robert H. Smith School of
Business, University of Maryland.

Source: www.infoworld.com