Use ajax to call the soap web service. Part 1: Construct a web service client

Source: Internet
Author: User
Tags websphere application server

James Snell (, software engineer, emerging technology, IBM

James Snell is a designer and Strategy expert in the emerging Internet technologies team in the IBM software group. In this group, he played a positive role in the evolving architecture and Implementation of Web service technologies. He isProgramming Web Services with soap(O'reilly and Associates) co-author. You can contact James through the

Introduction:This article describes how to use Asynchronous JavaScript and XML (Asynchronous JavaScript and XML, Ajax) design patterns to implement soap web service clients based on Web browsers.

View more content in this series

Mark this article!

Release date:January 16, 2006
Access status1059 views
Suggestion:0 (Add Comment)

Average score (1 in total)

This article is part 1 of a series of articles that demonstrate how to use Ajax design patterns for web applications to implement cross-platform JavaScript-based soap web service clients.

Ajax has been widely used in many well-known web application services, such as Gmail, Google Maps, Flickr, and By using asynchronous XML message transmission, Ajax provides a way for Web developers to expand the value and functions of their web applications. The Web Services JavaScript library introduced here extends this basic mechanism and enhances the Ajax design mode by introducing support for calling soap-based Web Services.

Call web services from a browser

Visit the Ajax technical resource center, an all-in-one center for Ajax programming model information, including many documents, tutorials, forums, blogs, wikis, and news. Any new information can be found here.

Calling the soap web service from a Web browser may be troublesome, because most popular Web browsers have slightly different aspects in generating and processing XML. All browsers implement consistent standards and have few standard APIs or functions for XML processing.

XMLHttpRequest API is one of the mechanisms supported by the browser implementation personnel, and is the core of the Ajax design pattern. Another article recently published by Philip McCarthy on the developerworks website details this API. XMLHttpRequest is a JavaScript Object used to execute asynchronous HTTP requests. Philip McCarthy describes a sequence diagram in his article (see figure 1). This diagram is helpful for understanding how XMLHttpRequest objects support Ajax design (see references, to obtain the link pointing to the full text ).

Figure 1. Philip McCarthy's Ajax sequence diagram

From this figure, you can clearly see how the XMLHTTPRequest object works. Some JavaScript running in the Web browser creates an XMLHttpRequest instance and a function for asynchronous callback. The script then uses the XMLHTTPRequest object to perform HTTP operations on the server. After receiving the response, call the callback function. This callback function may process the returned data. If the returned data happens to be XML, the XMLHTTPRequest object will automatically use the XML processing mechanism built in the browser to parse the data.

Unfortunately, the main problem with Ajax is that the XMLHTTPRequest object automatically parses the detailed XML Process. For example, assume that the data I'm requesting is a SOAP envelope that contains elements from many different XML Namespaces and I want to extractyetAnotherElementMedium attributeattr. (See Listing 1)

Listing 1. a soap envelope containing multiple namespaces

                <s:Envelope   xmlns:s=""   xmlns:xsd=""   xmlns:xsi="">  <s:Header/>  <s:Body>    <m:someElement xmlns:m="http://example">      <n:someOtherElement         xmlns:n="http://example"         xmlns:m="urn:example">        <m:yetAnotherElement           n:attr="abc"           xmlns:n="urn:foo"/>      </n:someOtherElement>    </m:someElement>  </s:Body></s:Envelope>

In Mozilla and FirefoxattrAttribute values are very simple, as shown in Listing 2.

Listing 2. Methods for retrieving ATTR attribute values in Mozilla and Firefox cannot be used in Internet Explorer

                var m = el.getElementsByTagNameNS(  'urn:example',  'yetAnotherElement')[0].    getAttributeNS(      'urn:foo',      'attr');alert(m); // displays 'abc'


Because many actual security problems are involved, by default, in most Web browsers, the XMLHTTPRequest object is restricted to interacting with resources and services in the domain where the web page you are viewing resides. For example, if I am accessing a page in the, XMLHttpRequest will only allow access to resources in the domain. This precaution is necessary to prevent malicious application code from conducting improper access to information that it should not be accessed. Because the Web service client described here is based on XMLHttpRequest, this restriction applies to the Web service that you will call.

If you need to be able to access web services in another domain, you can use the following two reasonable solutions:

  • Digitally sign JavaScript.By digitally signing a Javascript script, you can tell the web browser that it can trust the script to not execute any malicious activity, and the restrictions on the data that XMLHttpRequest can access should also be canceled.
  • Use a proxy.A simple solution is to pass all requests from XMLHttpRequest through the proxy Resources in the domain of the loaded page. The proxy forwards the XMLHttpRequest request to a remote location and returns the result to the browser. From the XMLHTTPRequest object perspective, this interaction occurs within the existing security configuration.

Unfortunately, the above Code cannot be run in Internet Explorer version 6, because the browser not only does not implement the getelementsbytagnamens function, in fact, a bad method is used to treat the prefix of an XML namespace as part of its element and attribute name.

Internet Explorer does not support XML Namespaces, which makes it difficult to process the dense XML format of namespaces. For example, soap is used independently of a browser. Even if you want to perform some simple operations like extracting the property values in the results, you must write special code that can achieve consistent expected behavior in multiple browsers. Fortunately, this special code can be encapsulated and reused.

To call web services from a Web browser and process soap messages reliably, You need to first understand some security issues (see "about security" on the sidebar "). In addition, you also need to write a Javascript script Library (Figure 2) to abstract inconsistencies in the XML Implementation of the underlying browser, so that you can directly process Web Service data.

Figure 2. using JavaScript to call Web Services in a web browser using Web Services JavaScript Library

The Web Services JavaScript Library (WS. JS) in Figure 2 is a set of JavaScript objects and practical functions that provide basic support for soap 1.1-based Web Services. WS. js defines the following objects:

  • WS. Call: A web service client packaged with XMLHttpRequest
  • WS. QNAME: XML qualified name implementation
  • WS. Binder: Basics of custom XML serializer/deserializer
  • WS. Handler: The basis of the request/Response Processing Program
  • Soap. Element: Encapsulates the basic soap elements of the xml dom.
  • Soap. Envelope: The SOAP envelope object extends the soap. Element
  • Soap. Header: The SOAP header object extends the soap. Element
  • Soap. Body: The soap body object extends the soap. Element
  • XML: Cross-platform practical method for processing XML

The core of WS. JS is the WS. Call object, which provides methods to call Web Services. WS. Call interacts with XMLHttpRequest objects and processes soap responses.

The Ws. Call object exposes the following three methods:

  • Add_handler.Add a request/response handler to the processing link. The handler object is called before and after the Web Service is called to support scalable pre-adjustment usage and post-call processing.
  • Invoke.Sends the specified soap. Envelope object to the Web service, and then calls the callback function after receiving the response. Use this method when calling a web service that uses the Document Style encoded in text XML.
  • Invoke_rpc.Create a soap. Envelope that encapsulates the RPC style request and send it to the web service. Call the callback function when a response is received.

Generally, the WS. Call object is only a thin wrapper located at the top layer of the XMLHTTPRequest object. This Wrapper can perform many simplified operations. These operations include setting the soapaction HTTP header required by the soap 1.1 Standard.

Back to Top

Use ws. js

The APIS provided by the Web Services JavaScript library are very simple.

Soap. * object (SOAP.Element,SOAP.Envelope,SOAP.HeaderAndSOAP.Body) Provides a method for building and reading Soap envelopes, as shown in listing 3. The underlying details of the XML Document Object Model can be abstracted smoothly.

Listing 3. Construct a SOAP envelope

                var envelope = new SOAP.Envelope();var body = envelope.create_body();var el = body.create_child(new WS.QName('method','urn:foo'));el.create_child(new WS.QName('param','urn:foo')).set_value('bar');

Listing 4 shows the SOAP envelope generated by the code in listing 3.

Listing 4. Construct a SOAP envelope

                <Envelope xmlns="">  <Body>    <method xmlns="urn:foo">      <param>bar</param>    </method>  </Body></Envelope>

If the SOAP envelope you are creating represents an RPC-style request, the soap. Body element provides a simple method.set_rpc(As shown in listing 5), this method can construct a complete RPC request that contains a specified operation name, a specified input parameter array, and a soap-encoded Uri.

Listing 5. Construct an RPC Request envelope

                var envelope = new SOAP.Envelope();var body = envelope.create_body();body.set_rpc(  new WS.QName('param','urn:foo'),  new Array(    {name:'param',value:'bar'}  ), SOAP.NOENCODING);

Each parameter is transmitted as a JavaScript Object Structure and may have the following attributes:

  • Name.A string or ws. QNAME object with the specified parameter name.Required.
  • Value.Parameter value. If the value is not a simple data type (such as a string, integer, or other), you should specify a ws. binder that can serialize the value to an appropriate XML structure.Required.
  • Xsitype: Ws. QNAME (for example,xsi:type="int"Correspondingxsitype:new WS.QName('int','')).Optional.
  • Encodingstyle: Identifies the URI of the soap encoding style used by the parameter.Optional.
  • Binder: Ws. binder that serializes parameters into XML.Optional.

For example, if the name of the parameter to be specified is "ABC", the XML namespace is "urn: foo", the xsi: type is "int", and the value is "3 ", then I will use the following code:new Array({name:new WS.QName('abc','urn:foo'), value:3, xsitype:new WS.QName('int','')}).

Once I build soap. envelope for the service request, I will pass the soap. envelope toinvokeMethod To Call The encoding method in the envelope:(new WS.Call(service_uri)).invoke(envelope, callback)

Another option is to manually build soap. envelope. I will pass the WS. QNAME parameter, parameter array, and encoding style toinvoke_rpcMethod, as shown in Listing 6.

Listing 6. Use the WS. Call object to call the Web Service

                var call = new WS.Call(serviceURI); var nsuri = 'urn:foo';var qn_op = new WS.QName('method',nsuri);var qn_op_resp = new WS.QName('methodResponse',nsuri);    call.invoke_rpc(    qn_op,    new Array(      {name:'param',value:'bar'}    ),SOAP.NOENCODING,    function(call,envelope) {      // envelope is the response SOAP.Envelope      // the XML Text of the response is in arguments[2]    }  );

Before callinginvokeMethod orinvoke_rpcThe Ws. Call object creates a basic XMLHTTPRequest object, transmits it with an XML element containing the SOAP envelope, receives and parses the response, and then calls the provided callback function.

To expand the pre-processing and post-processing capabilities of soap messages, the WS. Call object allows you to register a set of WS. Handler objects, as shown in listing 7. These objects are called for each request, response, and error in the call cycle. You can implement a new handler by extending the WS. Handler JavaScript Object.

Listing 7. Create and register a response/response Handler

                var MyHandler = Class.create();MyHandler.prototype = (new WS.Handler()).extend({  on_request : function(envelope) {     // pre-request processing  },  on_response : function(call,envelope) {     // post-response, pre-callback processing  },  on_error : function(call,envelope) {  }});var call = new WS.Call(...);call.add_handler(new MyHandler());

The handler is most useful for inserting or extracting information in the passed SOAP envelope. For example, you can assume that a handler automatically inserts an appropriate web service addressing element into the header of the SOAP envelope, as shown in the example in listing 8.

Listing 8. Example of a handler that adds a web service addressing operation header to a request

                var WSAddressingHandler = Class.create();WSAddressingHandler.prototype = (new WS.Handler()).extend({  on_request : function(call,envelope) {      envelope.create_header().create_child(        new WS.QName('Action','http://ws-addressing','wsa')      ).set_value('');  }});

WS. Binder object (listing 9) executes custom serialization and deserialization of the soap. Element Object. The implementation of WS. Binder must provide the following two methods:

  • To_soap_element.Serialize JavaScript objects to soap. element. The first parameter is the value to be serialized. The second parameter is soap. element, and the value to be serialized must be serialized as soap. element. This method does not return any value.
  • To_value_object.Deserializes soap. element into JavaScript objects. This method must return the deserialization value object.

Listing 9. ws. binding implementation example

                var MyBinding = Class.create();MyBinding.prototype = (new WS.Binding()).extend({  to_soap_element : function(value,element) {      ...  },  to_value_object : function(element) {    ...  }});

Back to Top

A simple example

I have provided an example project to illustrate the basic functions of the Web Services JavaScript library. The Web Service used in this demonstration (as shown in listing 10) has been implemented in WebSphere Application Server and provides a simple hello World function.

Listing 10. A simple Java-based "Hello World" Web Service

                package example;public class HelloWorld {  public String sayHello(String name) {    return "Hello " + name;  }}

After the service is implemented and deployed to WebSphere Application Server, the WSDL description of the service (listing 11) defines the SOAP message to be transmitted (used to call the hello World Service ).

Listing 11. code snippet of helloworld. WSDL

                <wsdl:portType name="HelloWorld">  <wsdl:operation name="sayHello">    <wsdl:input       message="impl:sayHelloRequest"       name="sayHelloRequest"/>    <wsdl:output       message="impl:sayHelloResponse"       name="sayHelloResponse"/>  </wsdl:operation></wsdl:portType>

By using the Web Services JavaScript library, you can implement a method to call the hello World Service, as shown in listing 12.

Listing 12. Using ws. Call to call the helloworld Service

                  var call = new WS.Call('/AjaxWS/services/HelloWorld');   var nsuri = 'http://example';  var qn_op = new WS.QName('sayHello',nsuri);  var qn_op_resp = new WS.QName('sayHelloResponse',nsuri);    call.invoke_rpc(    qn_op,    new Array(      {name:'name',value:name}    ),null,    function(call,envelope) {      var ret =         envelope.get_body().get_all_children()[0].          get_all_children()[0].get_value();      container.innerHTML = ret;      $('soap').innerHTML = arguments[2].escapeHTML();    }  );}</script>

Then, you can callsayHelloFunction to call the hello World Service. See listing 13.

Listing 13. Calling the sayhello Function

                <body><input name="name" id="name" /><input value="Invoke the Web Service"       type="button"        onclick="sayHello($('name').value,$('result'))" /><div id="container">Result:<div id="result"></div><div id="soap"></div></div></body>

The result 3 is displayed after the call is successful. Run this example in Mozilla, Firefox, and Internet Explorer to get the same result.

Figure 3. Hello world example in Firefox

Back to Top

Subsequent sections

With Web Services JavaScript library, you can simply merge basic soap web services into Web applications in a browser-independent manner. In the next section of this series, you can not only explore how to use this library to call more advanced Web Services Based on the WS-resource framework specifications, you can also understand how to extend the Web service function and integrate it into web applications.

Back to Top


Download Method

Sample project
19 KB

Information about the Download Method

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.