|By Berndt Hamboeck||
|February 1, 2002 12:00 AM EST||
"Web services are a new breed of Web application. They're self-contained, self-describing, modular applications that can be published, located, and invoked across the Web. Web services perform functions, which can be anything from simple requests to complicated business processes. A sample Web service might provide stock quotes or process credit-card transactions. Once a Web service is deployed, other applications (and other Web services) can discover and invoke the deployed service."
-IBM's Web Services Tutorial
The World Wide Web is mostly used as a source of information - the weather, the latest news, updates, downloading software, etc. Wouldn't it be great to go one step further and be able to request services. When I say services I don't mean a shop, I mean component services that could be used to build even bigger services.
For example, since Microsoft's Passport offers authentication services why should we build our own? We could use this service and go straight to writing our own (e.g., currency conversion), which could then be used by someone who would offer this service with his or her own (e.g., language translation or shipping information).
You might say that this can already be done since we have CORBA, RMI, Jini, and DCOM. This is true, but wouldn't it be great if everyone could write their own services and use whatever language they want to write components and clients, and anyone could access these services?
This is where SOAP comes into the picture. SOAP's implementations and tools are available in most programming languages, and in many cases for free. Developers get platform independence for Web services at little or no cost.
Introduction to SOAP
The Simple Object Access Protocol (SOAP) provides a mechanism for distributing objects over the Web. It's a way for developers to remotely make method calls upon classes and objects that exist on a remote server, without needing to know which language the objects are written in. It's the latest in a long series of similar projects like CORBA, DCOM, and XML-RPC.
SOAP defines the use of XML and HTTP to access services, objects, and servers in a platform-independent manner. It's a protocol that acts as the glue between heterogeneous software components.
Maybe you heard SOAP is a Microsoft-specific protocol. This is not true, although Microsoft offers an implementation of the specification. SOAP is supported and managed by a number of companies and has an open specification, which you can find at www.w3.org/TR/SOAP/.
We'll use Apache SOAP for our example, but you could also look at Microsoft's. Apache SOAP, an open-source implementation of SOAP v1.1 and SOAP messages with attachment specifications in Java, is developed by the Apache SOAP community.
How Does This Work?
A component installed on our application server will be our Web service that can be used by anyone. To access this service clients have to send a request. They don't know which language this service is written in and they don't care. If this request has the correct syntax, our component will be called and we'll send back a response that can be understood by everyone.
As I've already discussed, think of SOAP as a lightweight protocol for the exchange of information in a decentralized, distributed environment. It's an XML-based protocol that consists of three parts, as stated on the W3C Web site: www.w3.org/TR/SOAP/#_Toc478383494.
The HTTP Header
In Listing 1 the URI, /soap/servlet/ rpcrouter, tells the server to route the request to the servlet sitting in EAServer. The host we're talking to is on our own machine, localhost.
The content-type header uses a value of text/xml. SOAP defines this value to identify an HTTP entity body that contains an XML-encoded method invocation or response. All SOAP requests and responses must use this content-type value to be recognized.
The character set may be specified, if not, the default is US-ASCII. Other acceptable character sets are UTF-8 and UTF-16. UTF-8 is recommended for maximum interoperability.
The content length may be specified; if it is, it must be correct.
SOAP doesn't define a traditional versioning model based on major and minor version numbers. A SOAP message must have an Envelope element associated with the http://schemas.xmlsoap.org/soap/envelope/ namespace.
The XML document stored at http:// schemas.xmlsoap.org/soap/envelope/ identifies the core elements and attributes of a SOAP message (envelope, header, and body). On receiving a document with this namespace, the receiver doesn't need to download the XML Schema. The <SOAP-ENV:Envelope.../> tag defines two additional namespaces as attributes, xmlns:xsi and xmlns:xsd, which are part of the XML namespace specification.
The Body element is encoded as an immediate child element of the SOAP Envelope XML element. The <SOAP-ENV:Envelope> must contain a single <SOAP-ENV:Body> element that contains a single element, the procedure call. Note that the procedure name must be a valid XML element name.
If our procedure getmessage needs parameters, we'd have to define them now. The names of the parameters are significant; the order is not. Parameter type is indicated by the xsi:type attribute. If we add a function with parameters to the server component and call this new function by passing the two parameters, the request would contain the following:
The names of the parameters are significant; the order isn't. A procedure call may not take any parameters (as in our example), so the procedure element must not contain subelements. Table 1 provides the value types supported for parameters.
A value can also be null, which is specified by an XML element with an attribute, xsi:null, whose value is 1: <p1 xsi:null="1"/>.
Note that the SOAP protocol doesn't specify or imply the method for processing. The supplier could run a CGI script, invoke a servlet or a PB component, or perform any other process that would produce the appropriate response to the request. The response would be in the form of an XML document in which the results are placed in an element whose name matches the method name suffixed by "Response."
Let's take a closer look at what we get back from our component call. If we call the component the same way we call a standard PB component, we'd get back our "Hello World" String, but with SOAP it's a little different (see Listing 2).
The HTTP Header
Unless there's an error, return 200 OK. The content type is text/xml. Content length may be specified; if it is, it must be correct.
The body of the response is (of course) in XML, a single <SOAP-ENV:Envelope> element. The <SOAP-ENV:Envelope> must again contain a single <SOAP-ENV:Body> element that contains a single element, which is the returned value of the procedure.
The single element contained in the <SOAP-ENV:Body> has an arbitrary name that must match the name of the called procedure, with "Response" tacked on to the end of its name. Let's call this element the wrapper for the response. Even this isn't the actual value of the response, which is contained in the single optional subelement of the wrapper and must be a valid parameter. The namespace of the wrapper element should match the namespace in the request. If the wrapper doesn't have any subelements, the procedure didn't return a value.
Let's Do It with Our Tools
Download Apache SOAP from http://xml.apache.org/dist/soap/version-2.2/soap-bin-2.2.zip. Unzip soap-bin-2.2.zip to C:\soap.
Jason Weiss wrote a good article that explains this step-by-step: "Installing Apache SOAP 2.2 with Sybase EAServer 3.6.1 and 4.0," http://my.sybase.com/detail?id=1013352.
The Server Component
Create a directory where we'll store our PowerBuilder and PowerJ Workspace (C:\soap).
In PowerBuilder, create a new Workspace called soap (File -> New -> Workspace) in your new directory and start EAServer 4. Create a new EAServer component (File -> New -> Target) (see Figure 1).
Follow the wizard and enter in the following information, accepting the default where nothing is specified:
- Application name: Soapapp
- EAServer component name: Soapapp
- Package name: Soap
- Specify transaction support: Check auto demarcation/deactivation
- Project: p_deploy
Open p_deploy and deploy your component. Now open Jaguar Manager and connect using jagadmin and an empty password. Go to your SOAP package where you can see your component and edit the property (see Figures 3 and 4).
com.sybase.jaguar.component.home = soap::soapappHome
Generate EJB stubs and skeletons (RMB on soapapp):
- Generate stubs: Checked
- Generate Java stubs: Checked
- Generate Java files: Check radio button
- Compile Java stubs: Checked
- Generate skeletons: Checked
In PowerJ, create a new workspace called soap (File -> New Workspace) in C:\soap. Create a new Java classes target (File -> New... from within Workspace View). Follow the wizard and enter in the following information, accepting the default if nothing is specified:
Create a new standard class (RMB logonClasses Target -> New... from within Workspace View).
Follow the wizard and enter in the following information, accepting the default if nothing is specified:
Add C:\soap-2_2\lib\soap.jar to the Build Options ClassPath or to your global ClassPath (see Figure 5).
Now change the source code for PBClient.java (see Listing 3).
We tell SOAP that we have an EJB (we generated EJB stubs and skeletons, right?) sitting on EAServer waiting for our clients. Let's create an XML file (see Listing 4).
We use this file to deploy to SOAP. We have to create a batch file that will do this for us (see Listing 5).
This file could be used to deploy any correct DeploymentDescriptor.xml to SOAP. It simply takes the file and calls the SOAP servlet that's sitting in your EAServer (localhost:8080). So let's deploy....
You'll see that urn:testprovider was just deployed to SOAP (see Figure 6). The other SOAP service, urn:string-service, may be shown next time.
Test the Web Service
I wrote the files DeploymentDescriptor.xml, deploy.cmd, and run.bat outside PowerJ and imported them to the soapClasses target.
If you created everything, your workspace should look like mine (see Figure 7). Tip: Enable Show All Files on the soapClasses target to see the JAR file.
Apache SOAP includes an application in which you can view the request to SOAP and the answer to the client. Start it in a DOS box with the command:
java org.apache.soap.util.net.TcpTunnelGui 8090 localhost 8080
You should have C:\soap-2_2\lib\soap.jar in your ClassPath.
To test your Web service use the batch file provided in Listing 6. You'll be able to see the request and the response in the TcpTunnelGui and your DOS box should look like Figures 8 and 9.
If you have problems with the XML parsers look for the file %SYBASE%\Shared\Sun\ jdk122\jre\lib\ext\jaxp.jar and remove it, if it exists.
If you have any problems deploying the PB component to EAServer, visit the Sybase newsgroups. This is a great source with lots of helpful people.
If your run.bat file fails because it can't find the EJB, try to restart EAServer. Refreshing the package doesn't help after creating the Home interface by EAServer.
The only problem I had was with the wrong version of the crimson.jar file:
File name Size
SOAP is a Remote Procedure Calling protocol that works over HTTP. The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML. Procedure parameters and returned values can be scalars, numbers, strings, dates, etc., and can also be complex record and list structures.
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- Creation and Consumption of Web Services with PowerBuilder
- Cloud People: A Who's Who of Cloud Computing
- DDDW Tips and Tricks
- Cloud Expo 2011 East To Attract 10,000 Delegates and 200 Exhibitors
- Working with SOA & Web Services in PowerBuilder
- Dynamically Creating DataWindow Objects
- Cloud Expo, Inc. Announces Cloud Expo 2011 New York Venue
- OLE - Extending the Capabilities of PowerBuilder