Create And Consume SOAP Web Services Using WSDL

NuSOAP is a group of PHP classes that allow developers to create and consume SOAP web services. It does not require any special PHP extensions. The current release version (0.6.7) of NuSOAP at the time this was written (03-November-2004), supports much of the SOAP 1.1 specification. It can generate WSDL 1.1 and also consume it for use in serialization. Both rpc/encoded and document/literal services are supported. However, it must be noted that NuSOAP does not provide coverage of the SOAP 1.1 and WSDL 1.1 that is as complete as some other implementations, such as .NET and Apache Axis.

This document follows up Introduction to NuSOAP, Programming with NuSOAP, and Programming with NuSOAP Part 2 with additional samples that demonstrate how to use NuSOAP to create and consume SOAP web services using WSDL.

Hello, World Redux

Showing no imagination whatsoever, I used the ubiquitous “Hello, World” example in Introduction to NuSOAP. In that document, I showed the SOAP request and response exchanged by the client and server. Here, I extend that sample to use WSDL.

A WSDL document provides metadata for a service. NuSOAP allows a programmer to specify the WSDL to be generated for the service programmatically using additional fields and methods of the soap_server class.

The service code must do a number of things in order for correct WSDL to be generated. Information about the service is specified by calling the configureWSDL method. Information about each method is specified by supplying additional parameters to the register method. Service code for using WSDL is shown in the following example.

<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the server instance
$server = new soap_server();
// Initialize WSDL support
$server->configureWSDL('hellowsdl', 'urn:hellowsdl');
// Register the method to expose
$server->register('hello',                // method name
    array('name' => 'xsd:string'),        // input parameters
    array('return' => 'xsd:string'),      // output parameters
    'urn:hellowsdl',                      // namespace
    'urn:hellowsdl#hello',                // soapaction
    'rpc',                                // style
    'encoded',                            // use
    'Says hello to the caller'            // documentation
);
// Define the method as a PHP function
function hello($name) {
        return 'Hello, ' . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

Now for some magic. Point a Web browser at this service, which in my environment is at http://localhost/phphack/hellowsdl.php. The HTML that is returned to your browser gives you links to view the WSDL for the service or view information about each method, in this case the hello method. The screen should look something like this.

The Basics Of Working With Web Services

ADF to fully exploit the use of Web services for communicating with ArcGIS Server services. Directly as a developer with the ADF and ArcGIS Server, it is important to understand the use of SOAP and its relationship with the WSDL file with ArcGIS. This article describes some of the basics of working with Web Services, SOAP and WSDL with ArcGIS Server. After this article you must read some documents that explain how the ideas discussed here apply in relation to a specific ADF.


Web services applications can communicate via messages from different protocols. Because Web services means for communication between applications in the program itself is written in a programming language, is language-independent communications. XML is the format used to maintain present information about applications. XML messaging via SOAP (Simple Object Access Protocol). SOAP defines a header and a valid means of message exchange. This exchange of messages is usually via HTTP, but actually a protocol such as SMTP, FTP, or DCOM, to be known. SOAP, XML, and wrap the message so that the applications received and processed they can be transferred appropriaptely.

 

WSDL, but also explains what Web services do not, what methods it has, what parameters and the guy who knows how you and the port used for communication. WSDL defines the valid content of XML SOAP messages are transmitted. WSDL is a specification, such as IDL, interfaces and parameters to describe the Web. The available methods are usually together in “port”, which can be viewed as a Web destination for the various activities they are interested in groups. A WSDL may contain one or more ports. Has the WSDLs provided by ESRI, a single interface for WSDL. For example, all methods show the MapServer WSDL recorded as part MapServerPort. Another feature of the Web service described in WSDL that specifies a protocol for sending messages, and optionally the URL of the corresponding server. WSDL specification does all this work in a very general, so that the toolkit in various languages, such as the Axis in Java, to generate code from WSDL descriptions.

 

WSDLs and ArcGIS Server
If you are in the installation directory under the XmlSchema found eight WSDL file. Each fits the description of the ArcGIS Server Web service can publish. Each WSDL corresponds roughly with the ArcObjects classes, for example, corresponds to the object MapServer.wsdl MapServer and GeoDataServer.wsdl GeoDataServer consistent with the object. Because Web services are usually only text messages (XML) to send between applications, there are differences in method signatures and data types from WSDL and ArcObjects. If you are open GeocodeServer.wsdl there are two major stages, you need to understand. The first part is <types> element and the second part is an element PortType.

 

Value of the items
<types> All the elements that defines the data type for WSDL, and valuables. This section contains definitions for all elements that are used as parameters to a web service method to pass. Object value can consist of objects of value, but at the end of the “end” must be a valid data type schema type such as String, int length or XML data. When a Java toolkit for the sale of all classes of the Java-like element in the WSDL Java objects of value, as the old Java objects (POJOs). For example, if you look at the point in the WSDL Look, this is an XML representation of a point sufficient to ArcObjects Web service operation:

 

<xs:complexType name=”PointN”>
<xs:complexContent>
<xs:extension base=”Point”>
<xs:sequence>
<xs:element name=”X” type=”xs:double”/>
<xs:element name=”Y” type=”xs:double”/>
<xs:element name=”M” type=”xs:double” minOccurs=”0″/>
<xs:element name=”Z” type=”xs:double” minOccurs=”0″/>
<xs:element name=”ID” type=”xs:int” minOccurs=”0″/>
<xs:element name=”SpatialReference” type=”SpatialReference” minOccurs=”0″/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>

 

The Javadoc for the class generated using the AXIS toolkit, shows a Java class which is very similar to a POJO. From the WSDL definition we can see that M, Z, ID, and SpatialReference are not required properties since their minOccurs attribute is equal to 0. Therefore when you need to use a PointN value object you can create it using the default construct, set the X and Y, and then pass it as a parameter. There is no need to create the object on the Server Context, it is created on the local machine. When you are setting the object’s properties since they are set locally no remote call is made to the ArcGIS serverl.

Port Usage

Inside the <portType> element is the listing of all the methods that can be called on the web service. For example, one of the calls you can make is ReverseGeocode, which takes a point and figures out the closest address.

<operation name=”ReverseGeocode”>
<input message=”e:ReverseGeocodeIn”/>
<output message=”e:ReverseGeocodeOut”/>
</operation>

There is a definition for the input message (the input parameters) and the output message (the returned values) in another section of the WSDL. In this case they are defined earlier in the file as <message> elements, which are then mapped to <types>. Through this mapping you can see that a ReverseGeocode input message contains a location, which is a point, a boolean to indicate if intersections should be returned, and some properties in a PropertySet

<xs:element name=”ReverseGeocode”>
<xs:complexType>
<xs:sequence>
<xs:element name=”Location” type=”Point”/>
<xs:element name=”ReturnIntersection” type=”xs:boolean”/>
<xs:element name=”PropMods” type=”PropertySet”/>
</xs:sequence>
</xs:complexType>
</xs:element>

When the WSDL is used to generate Java proxies through AXIS a class will be generated named GeocodeServerPort which contains all the methods you can call on the ArcGIS Server GeocodeServer object using web services. The GeocodeServerPort object is instantiated in the local JVM but any method call on this class will execute a remote call to the server. Any object returned from the server will be a value object and therefore accessing its properties will not require calls to the server. Therefore, the only methods in the Java classes generated from the WSDL which make remote calls will be those methods exposed on a *Port object.

Implications for ArcGIS Server Developer

Using SOAP has several advantages for ArcGIS Server developers. The greatest advantage is that the value objects are Java objects in the local JVM. Because they reside in the local JVM and they are pure Java they are easier to debug and work with in general. Another serious advantage is that the only remote calls are those on the *Port objects. When using ArcGIS Server with the server API, each call to set a variable or execute a GIS operation is a remote call. Because the value objects are in the local JVM all calls to their mutators are local calls. When you call one of the methods on a *Port object you pass the value object as a parameter. The returned objects are also value objects, so retrieving values from this object are local calls as well. This overall reduction in remote calls greatly increases the performance of your application.

Here is an example which comes from the example below. It uses Value objects and the MapServerPort to query the count of features in a layer in the map. Using the server API every method call, from creating the envelope to the query feature count call would be a remote method call.

// The envelope is a value object so this constructor is not a remote call
EnvelopeN env = new EnvelopeN(webExtent.getMinX(), webExtent.getMinY(), webExtent.getMaxX(), webExtent.getMaxY(),
null, null, null, null, null);
// make a spatialfilter value object with the required parameters – none of these method calls are remote
SpatialFilter spatialFilter = new SpatialFilter();
spatialFilter.setFilterGeometry(env);
spatialFilter.setSpatialRel(EsriSpatialRelEnum.esriSpatialRelIntersects);
spatialFilter.setWhereClause(“”);
spatialFilter.setSearchOrder(EsriSearchOrder.esriSearchOrderSpatial);
spatialFilter.setSpatialRelDescription(“”);
spatialFilter.setGeometryFieldName(“”);

int layerId = layer.getId();
//because queryFeatureCount is found on the MapServerPort the call to queryFeatureCount goes back
//to the server which can throw an RemoteException
try {
numberOfFeatures =  mapServer.queryFeatureCount(mapServer.getDefaultMapName(), layerId, spatialFilter);
} catch (RemoteException e){}

There are also some drawbacks, especially for current ArcGIS Server programmers. Because of the requirements of the WSDL using simple types and the way different toolkits generate default values, some of the generated objects need more properties set before the methods will work. For example, using an Element for custom graphics needs to have its color set when using SOAP but not using the Server API. The implications of this for current ArcGIS Server developers is that your code will not translate directly and that you may have to set more values before the method call.

Now that you have basic understanding of the ArcGIS Server web services, you can go on to reading about how these generated Java proxies are used in the Web ADF and the Enterprise ADF. The Javadoc for the generated Java proxies can be found by themselves or as part of the Javadoc for the Web ADF and the Enterprise ADF

The custom command and tool example shows using the Value objects and Port calls.

Edit Into A SOAP Envelope

An application that depends largely on the work of the SOAP web service asp.net much in the simulator and then hit with a shock that CoreServices library function that does not contain all web services available on the iPhone. I keep hoping that this feature was recently added.

All my code depends on receiving the object NSArray and NSDictionary key, and do not want to edit into a SOAP envelope to create the missing features emulate approval of the request is REST. I can only method used to make web service call and the same code base. I thought I share to all in this together.

Fortunately asp.net and is compatible with the REST style requests (I am not aware of this earlier today), so no changes are needed in the web server.

To demonstrate here the call to a simple method called “SayHello”. You pass in name and it returns a single item called “string” that contains “Hello [yourname]“. The code will work with more complex objects with child properties as well, and return them as NSDictionary and NSArray objects, but for simplicity I’m using “SayHello”.

Code :

NSArray *keys = [NSArray arrayWithObjects:@"userName", nil];
NSArray *objects = [NSArray arrayWithObjects:@"jeremy", nil];
NSDictionary *params = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSDictionary *wsResponse=[WebServices callRestService:@"SayHello" :params];

NSString *responseString=[wsResponse objectForKey:@"string"];

 

callRestService is a helper method I created in a class called Webservices. This code was exactly the same before except the helper method was called callSoapService.

WebServices.m contains two methods. getRestUrl just appends all the method parameters into a url to make the REST request. callRestService uses the build-in NSXMLParser class to retrieve the xml and sends it to a custom class called XmlParser to handle the callbacks and create the NSDictionary result,

WebServices.m

Code:

+(id)callRestService: (NSString *) methodName : (NSDictionary *) params
{
        NSURL *url=[WebServices getRestUrl: methodName : params];
        XmlParser *xmlParser = [[XmlParser alloc] init];

        NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
        [parser setDelegate:xmlParser];
        [parser setShouldProcessNamespaces:NO];
        [parser setShouldReportNamespacePrefixes:NO];
        [parser setShouldResolveExternalEntities:NO];
        [parser parse];
        [parser release];
        return xmlParser.result;
}

+(NSURL *)getRestUrl: (NSString *) methodName : (NSDictionary *) params
{
        NSString *url=@"http://services.mywebsite.com/mywebservice.asmx/";
        url=[url stringByAppendingString:methodName];

        BOOL firstKey=TRUE;
        for (NSString *key in params)
        {
               NSString *value=[params objectForKey:key];
               if (firstKey) url=[url stringByAppendingString:@"?"]; else url=[url stringByAppendingString:@"&"];
               url=[url stringByAppendingString:key];
               url=[url stringByAppendingString:@"="];
               url=[url stringByAppendingString:value];
               firstKey=FALSE;
        }
        return [NSURL URLWithString:url];
}

 

The final step is to create the XmlParser handler. This class keeps track of each open and close tag to build an object tree containing NSMutableArray NSMutableDictionary and NSString objects.

XmlParser.h

Code:

 

#import <Foundation/Foundation.h>


@interface XmlParser : NSObject {
        NSMutableDictionary *result;
        NSString *currentElementName;
        NSString *currentElementValue;
        NSMutableArray *parentArray;
}

@property (nonatomic, retain) NSMutableDictionary *result;
@property (nonatomic, retain) NSString *currentElementName;
@property (nonatomic, retain) NSString *currentElementValue;
@property (nonatomic, retain) NSMutableArray *parentArray;


- (void)parserDidStartDocument:(NSXMLParser *)parser;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;

@end

XmlParser.m

Code:

#import "XmlParser.h"


@implementation XmlParser
@synthesize result;
@synthesize currentElementName;
@synthesize currentElementValue;
@synthesize parentArray;


- (void)parserDidStartDocument:(NSXMLParser *)parser
{
        result=[[NSMutableDictionary alloc] init];
        parentArray=[[NSMutableArray alloc] init];
        [parentArray addObject:result];
        currentElementName=@"";
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
        if (qName) {
               elementName = qName;
        }
        currentElementValue=@"";
        if (currentElementName!=@"")
        {
               id newParent=NULL;
               if ([currentElementName isLike:@"*Array*"])
               {
                       newParent=[[NSMutableArray alloc] init];
               } else {
                       newParent=[[NSMutableDictionary alloc] init];
               }
               [parentArray addObject:newParent];
        }
        currentElementName=elementName;
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
        if (qName) {
               elementName = qName;
        }

        if (currentElementName==@"")
        {
               //We're adding a container with children.  Add it to the parent and remove this item fromt he parentArray
               int currentIndex=[parentArray count]-1;
               int parentIndex=currentIndex - 1;
               id currentChild=[parentArray objectAtIndex:currentIndex];
               id currentParent=[parentArray objectAtIndex:parentIndex];

               if ([currentParent isKindOfClass:[NSMutableArray class]])
               {
                       [currentParent addObject:currentChild];
               } else {
                       [currentParent setObject:currentChild forKey:elementName];
               }

               [parentArray removeObjectAtIndex:currentIndex];
        } else {
               //We're adding a simple type element
               int currentIndex=[parentArray count]-1;
               id currentParent=[parentArray objectAtIndex:currentIndex];
               if ([currentParent isKindOfClass:[NSMutableArray class]])
               {
                       [currentParent addObject:currentElementValue];
               } else {
                       [currentParent setObject:currentElementValue forKey:currentElementName];
               }
        }
        currentElementName=@"";
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
        currentElementValue=string;
}

@end

 

 

That’s it. I’m sure it’s not the cleanest code (This is my very first XCode app) and there may be a better way of doing this, but it saved me from having to rewrite all my code that was retrieving data from SOAP services. I’ve seen tons of other people with the same problem and no solutions so far.

ColdFusion MX (CFMX) Is Easy Using Web Services

One of the main advantages of ColdFusion MX (CFMX) is easy you can build applications using web services.
Why advertise web services and real applications creep down, ease of use make the CFMX development of attractive options. Here I will show how CFMX makes it easy to call a web service, which shows how to query and return data from the interface is web services Amazon.com ‘s have been introduced recently.

 

Before you start, you need to go to Amazon Web Services site, download the development kit and chip development (ie, identity card number) to get. Sending this signal depends on the Amazon Web Services, and is a way to Amazon on their sites as partners in identifying and paying referral sales. Remove the sample is free, and by the members, if required. For example, all you need is the key to development.

 

Do a keyword
To begin, I would like to check Amazon.com to several search terms and display results. Developer’s Kit Documentation is a section that explains the format of the study and explain the structure of the response. There are two things to consider here.

First, the document states that the method keyword requests a search, there are several values ??that must be provided. These are: keyword, page, fashion, label, type, class and devtag. About the variable reported in the literature. At first glance you may think will be the Amazon Web service to call and pass arguments to each of the values, such as the code in Listing A.

But that’s not how it works. It takes “a little digging around and trying, but finally found a solution: Amazon want you to have a single variable, the keyword query the values ??of a table or structure so that the correct approach would be the first to build. Structural investigations and occupied by order of the Amazon as an argument. B contains a list of job codes that describe how the Amazon to find a list of all products as “hell” key words.

You can see that my application search parameters required type of investigation, the set consists of the dispute. Amazon said it will seek the light (not heavy) research, basic information about the product, and therefore faster.

After your application is successful format, which offers various products for research, relevant research in Listing B. Each array element contains information about this product, and shows users how to very easily, as shown in C. Register

You can get information on products such as return the application and documentation are described correctly. In the above example, the loop at the output range of products and a small image (getImageUrlSmall) product name (getProductName), artists (getArtist), and finally price (getListPrice).

You can also see that my name links to the item’s product information. Data for each object Amazon.com link to the article Amazon page for more information on its website, so you can only use this link. But you may not want to distribute Amazon customers first, maybe I want to stay on the website “I am a little more. To do this, a detailed half-page issue.
Amazon Web Services API also supports application ASIN ago, a unique identifier for each product Amazon sells. Through a series of information and specifications ASIN ASIN pages from data such as Amazon, as shown in Listing D, I request access to information about this product. You can ask to see the kind of research is defined here, too heavy, which means that we will return information about the products that I make my first application, which was created to fight.

 

Code in Listing D is the same, previously known as Web services. But this time I was on the first page of the ASIN change the URL. As can be seen from the inlet and outlet is the same as before (code B), but this time, because choosing different weight to the results, I have more information about the product in the workplace.

 

For example, data capture and display the page larger product image, sales network and a few comments, not the details of an application to fight again. API documentation describes all types of data access, the most interesting. You can call the same product, UPC, publisher, age, and the track list.

 

Amazon products are available through the API, including DVDs, software and books. Amazon also offers a way to allow people to add items to your shopping wish list for Amazon, and buy stuff. So if an affiliate, you can actually make money on your website.

Request additional information to consider is looking for writers and special features such as search and tag to your list of Amazon. Code to call the third party web service similar to the example I gave above. Just check the documentation to determine what needs to be special needs of data and format the results will be returned.

We began to reveal the most useful web services, and acceleration. I hope this example shows how easy it is to use ColdFusion MX to use Amazon Web Services. When it comes to Web services allow developers to facilitate the ColdFusion CFMX benefit greatly from a standard of attractiveness.

Rest Of The Way The Web Interface Main Services

For two years, the publicity associated with the Simple Object Access Protocol (SOAP) does not apply to almost fade, although the increase based on his opponent. While some critics are tired of hearing, Web services, architects are few Internet argument surprisingly well to choose soap: The better way is to create a slide show Web services that the state transfers (AN).

 

The AN-old philosophy of the new technology. While the soap seems to be the first phase of the development of the Internet to launch with the new requirements of the philosophy of AN to support the principles and protocols of existing facilities to create many web strong. This means that developers can understand HTTP and XML Web services to build to start immediately, without the packaging than those normally used for the development of Internet applications.

 

Flexible Interface
The rest of the way the Web interface main services, which are already known and widely used to write: URI. For example, can reveal the price of the service, where users enter the stock symbol on the stock market, real-time pricing to provide as simple as writing on the Web server that the URI: http:// www. somebrokerage.com / quote? = Symbol QQQ.

 

An application from any client or HTTP server to easily access services using HTTP GET support. Depending on how the service provider to write the script, the result of the HTTP response as simple as one of the many rules and the thread of the current price of a particular symbol. Or it could be an XML document.

 

Interface method has significant advantages over SOAP services. Any developer can understand how the URI can create and edit their Web access means soap, however, requires special skills that the new XML specification, and most of the developers kit make a soap request and explain the results.

 

Light the bandwidth
Another advantage of the calm surface, the questions and answers short. Asks SOAP XML wrapper around each application and respond. After the column name and type declaration, the stock four or five numbers and the SOAP response costs by more than 10 times the number of bytes the same reaction to the so-called PART.
Proponents argue that rigid soap essential element for distributed applications. In practice, even if the two applications, one type of data and services in advance of the data requests and responses for any reason whatsoever.

 

How do I know the data types and their position in the first reaction? PART Like soap, is still the same document with the edges of the input and output parameters. The good thing about AN the flexibility that developers can a WSDL file for their benefits to make a statement if necessary write access. Otherwise, the statement as a simple web page, people read to say: “Give this service a number of entries in the form q = icon, which is the current price per share of text chains.”

 

Security Guard
Perhaps the most interesting aspect of PART Vs. Soap in the security discussions. Although the area, said an appeal sent by the remote procedure is standard HTTP SOAP port is a good way to get your support for Web services in the organization, the proponents believe that the practice of design does not ensure the security network. PART calls over HTTP or HTTPS went well, but the rest of the manager (or firewall) to use for each message, the analysis of the HTTP request to make a difference. For example, a GET request is always safe because it does not change, by definition, not details. And “can only retrieve the data.

 

SOAP requests are normal, which in turn uses POST to communicate with the service provided. And look at the SOAP envelope, a task that most of the resources and uses firewall has no way of knowing if the application can retrieve only the data, or using a database table.

 

For authentication and authorization, SOAP provides the load in the hands of application developers. Methodology of the rest, but assume that the web server and is responsible for these tasks. The use of industry standards and common identity, such as LDAP servers, developers can do on the net for the hard work.
This helps the developers, not only, but also simplifies the task of administrators may want to use something as simple as a Web ACL, both in the same way as any other URI.

 

Not all
To be honest, not the best solution for all web services. The data must be protected so that there are no parameters and URI. And large amounts of data, such as purchase orders in detail, it can quickly be rotated beyond the boundaries of the URI. In this case, SOAP is a solid solution. Yet it is important to break and drive to take the soap, only when necessary. This allows for the development of applications that are easily accessible.

 

Fortunately, the philosophy YOUR Web developers to get. The latest version of the SOAP specification is currently certain services are exposed via URIs (even if the SOAP response message). In addition, users of Microsoft. NET services can be published via the GET request. All this marks a change in thinking about how Web services interface.

 

Developers understand that sending and receiving messages always express the best way to use SOAP. Sometimes the interface is not the answer simple text magic and save time and resources in the process.

Test The SOAP Messages

A client needs to develop SOAP web services. I’m involved in web services interface specifications and comply with specifications. JMeter and finally using XPath statements. Should not depend on the test unit “green bar”, but it worked.


The need is to test the SOAP messages that play on the network. At least one of the first customers to publish applications SOAP requests and responses from the XML SOAP service, instead of using SOAP kit. We need to ensure that the Web service interface to behave as expected, and the business logic behind the interface changes have no impact on the customer’s application.

 

Before the actual test in JMeter Google quickly reveals what is suitable for quick and dirty test. Tests can be written with JUnit and unity, but the solution may be in the client’s declaration that the e-mail is preferred. JMeter has a job, but has some problems.

 

The Recipe

  1. Download and install JMeter. (Activation.jar and mail.jar are required for SOAP testing. See installation notes.)
  2. Create a new Test Plan.
  3. Add a Thread Group to the Test Plan. Check that the number of threads is set to 1 and the number of loops is 1.
  4. For each test, add a Web Service (SOAP) Request samplers as a child of the Thread Group. Name them with a numeric identitifier for ease of reference. e.g. “1. Invalid Foo, Valid Bar”. You will need to supply the URL to the WSDL file and a fully formed SOAP request XML document.
  5. For each sampler, add as many XPath Assertions as you need to validate the result. XPath expressions can be used to check pretty much everything about the content and structure of XML documents.
  6. Add a View Results Tree listener to capture and display the requests and responses. Any tests that fail will be shown in red.
  7. Save your Test Plan.
  8. Run it.
  9. View results by clicking on the View Results Tree.
  10. Clear results before running the test again. Results are stored cumulatively, not replaced by each test.

Interpreting The SOAP Client

XMLSpy ® 2011 includes a full SOAP capabilities, including interpreting the SOAP client to WSDL (Web Services Description Language) documents to create SOAP requests, please send them to the web service and displays the SOAP response. It also contains powerful SOAP debugger.
In addition to SOAP 1.1, XMLSpy supports the latest version of the standard, 1.2, allows you to create and test Web services messages using the SOAP 1.2 and SOAP 1.1. According to the W3C, the benefits of the larger operational version 1.2, a better integration of the network increase, the flexibility and speed. XMLSpy now supports both SOAP 1.1 and 1.2, you can choose which version you want to embed applications in your Web service.
SOAP debugger
XMLSpy SOAP debugger works as a proxy between client and server web services web services, so that the WSDL 1.1/2.0, single step through Web Services transactions sent over HTTP or HTTPS inspection, review of each request and response XML document, set breakpoints feature (SOAP request or response), and even define conditional breakpoints that are triggered when a specific request or response, the selected data can be specified by an XPath query.

SOAP Is A Protocol

SOAP is a protocol for communication about the importance of the Internet, because most of the fact that it has become natural for a great development platform. SOAP is a protocol has also been very stable. WS-* War of the early years of the new millennium seems to die, and some very useful extensions to SOAP has been selected by the market.
Soap Many tools are also stabilized by the protocol. Inadequate compared with other SOAP good game. Unlike other tools are still very easy to use for most applications. But as more people and more literal document as a method of broadcast encryption option, the roots of prejudice and SOAP RPC started to show, and the kit is not possible:: Lite with XML.
As a result of the SOAP:: Lite has some compatibility issues with more modern servers, and clients are known. Responsible for SOAP:: Lite is now difficult. Sources note the signs of a complicated, serious intelligent Kulchenko Paul creates the SOAP: Lite. Result, the harassment experienced Perl programmer, and that makes many of them are done in the fear of the court. I am the highest recognition given to my office to join the module to the fact that – I work with some bright programmers with experience in Perl and everyone looks the SOAP:: Lite. And not as an impression of “good” surprise that people are healthy, but fear.
But I’m not trying to inflate my ego, I tried the stage for what should only be established in addition to SOAP Perl kit.
If SOAP:: Lite as an exciting project, the authors will be processed, it is essential that SOAP:: Lite to manage your code base much easier. SOAP:: Lite can be written to benefit large sectors of the house a lot of code before the record is very mature, before the era of WS-I, when the toolkit and other servers have been agreed and adopted a set of best practices. It should also be given the option to XML: RPC protocol is completely different under an entirely different set of conditions. SOAP:: Lite should switch to a model based on documents, instead of being pushed into a People’s Republic of China.
Therefore, SOAP:: Lite-writing. SOAP:: Lite must live “Lite” in its name. SOAP:: Lite should be built from scratch to meet the WS-I. Initially be built around the bad WSDL parser and engine. There should be more modular, so components can be easier to implement new and improved, no change for users and developers. You should take advantage of some Perl modules that have developed SOAP:: Lite are designed to reduce code complexity and ambiguity.
SOAP:: Lite needs your help. SOAP:: Lite needs a group of 2-3 people want to see the cooling kit is essential for developers of Perl and welcome a new era of recycling, communities, small businesses, the use and usefulness.
Running a project like this is not a trivial task. Which took many months of time and attention. And then they should be encouraged and nurtured.
The project is not from the beginning. This is the vision and the various codes that have been tested in SOAP:: Lite does not need to waste disposal. What we do is try, SOAP:: Lite easier to handle and easier to grok. What we hope to create a new module, called SOAP: Simple.

SoapUI Is Useful Tool For Testing Web Services

SoapUI is a useful tool for testing web services. Not only makes it possible to test deployed web services, but it also offers the possibility to mock any “external” service needed by the service you want to test. As a result, you can test your web service independently from any other external service.

The following basic example describes how to test a service that computes the price of a trip (TripPriceService). It invokes one service that returns prices for hotel rooms (HotelPriceService) and one service that returns prices for flights (FlightPriceService).

Formula : price = duration * rooms * getRoomPrice() + adults * getFlightPrice(from, to)

Here are the WSDLs of the three services.

 

TripPriceService.wsdl

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="TripPriceServiceFacadeService"
  targetNamespace="http://trip.price.service" xmlns:ns1="http://cxf.apache.org/bindings/xformat"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://trip.price.service" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified"
      targetNamespace="http://trip.price.service" xmlns:tns="http://trip.price.service" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="getTripPrice" type="tns:getTripPrice" />
      <xs:element name="getTripPriceResponse" type="tns:getTripPriceResponse" />
      <xs:complexType name="getTripPrice">
       <xs:sequence>
         <xs:element minOccurs="0" name="trip" type="tns:trip" />
       </xs:sequence>
      </xs:complexType>
      <xs:complexType name="trip">
        <xs:sequence>
          <xs:element name="adults" type="xs:int" />
          <xs:element name="duration" type="xs:int" />
          <xs:element minOccurs="0" name="from" type="xs:string" />
          <xs:element name="rooms" type="xs:int" />
          <xs:element minOccurs="0" name="to" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="getTripPriceResponse">
        <xs:sequence>
          <xs:element name="return" type="xs:float" />
        </xs:sequence>
      </xs:complexType>
      <xs:element name="TripPriceServiceException" type="tns:TripPriceServiceException" />
      <xs:complexType name="TripPriceServiceException">
        <xs:sequence />
      </xs:complexType>
    </xs:schema>
  </wsdl:types>
  <wsdl:message name="TripPriceServiceException">
    <wsdl:part element="tns:TripPriceServiceException" name="TripPriceServiceException">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getTripPrice">
    <wsdl:part element="tns:getTripPrice" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getTripPriceResponse">
    <wsdl:part element="tns:getTripPriceResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="ITripPriceServiceFacade">
    <wsdl:operation name="getTripPrice">
      <wsdl:input message="tns:getTripPrice" name="getTripPrice">
    </wsdl:input>
      <wsdl:output message="tns:getTripPriceResponse" name="getTripPriceResponse">
    </wsdl:output>
      <wsdl:fault message="tns:TripPriceServiceException" name="TripPriceServiceException">
    </wsdl:fault>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="TripPriceServiceFacadeServiceSoapBinding" type="tns:ITripPriceServiceFacade">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getTripPrice">
      <soap:operation soapAction="" style="document" />
      <wsdl:input name="getTripPrice">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getTripPriceResponse">
        <soap:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="TripPriceServiceException">
        <soap:fault name="TripPriceServiceException" use="literal" />
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="TripPriceServiceFacadeService">
    <wsdl:port binding="tns:TripPriceServiceFacadeServiceSoapBinding" name="TripPriceServiceFacadePort">
      <soap:address location="http://localhost:8080/trip-price-0.0.1-SNAPSHOT/webservices/TripPriceService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

HotelPriceService.wsdl

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions name="HotelPriceServiceFacadeService"
  targetNamespace="http://external.services/hotel" xmlns:ns1="http://cxf.apache.org/bindings/xformat"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://external.services/hotel"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xs:schema elementFormDefault="unqualified" targetNamespace="http://external.services/hotel"
      version="1.0" xmlns:tns="http://external.services/hotel" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="getRoomPrice" type="tns:getRoomPrice" />
      <xs:element name="getRoomPriceResponse" type="tns:getRoomPriceResponse" />
      <xs:complexType name="getRoomPrice">
        <xs:sequence />
      </xs:complexType>
      <xs:complexType name="getRoomPriceResponse">
        <xs:sequence>
          <xs:element name="return" type="xs:float" />
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
  </wsdl:types>
  <wsdl:message name="getRoomPrice">
    <wsdl:part element="tns:getRoomPrice" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getRoomPriceResponse">
    <wsdl:part element="tns:getRoomPriceResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="IHotelPriceServiceFacade">
    <wsdl:operation name="getRoomPrice">
      <wsdl:input message="tns:getRoomPrice" name="getRoomPrice">
    </wsdl:input>
      <wsdl:output message="tns:getRoomPriceResponse" name="getRoomPriceResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="HotelPriceServiceFacadeServiceSoapBinding" type="tns:IHotelPriceServiceFacade">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getRoomPrice">
      <soap:operation soapAction="" style="document" />
      <wsdl:input name="getRoomPrice">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getRoomPriceResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HotelPriceServiceFacadeService">
    <wsdl:port binding="tns:HotelPriceServiceFacadeServiceSoapBinding" name="HotelPriceServiceFacadePort">
      <soap:address location="http://localhost:8088/external-services-0.0.1-SNAPSHOT/webservices/HotelPriceService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

FlightPriceService.wsdl

<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="FlightPriceServiceFacadeService" targetNamespace="http://external.services/flight"
  xmlns:ns1="http://cxf.apache.org/bindings/xformat" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://external.services/flight" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified"
      targetNamespace="http://external.services/flight" xmlns:tns="http://external.services/flight"
      xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="getFlightPrice" type="tns:getFlightPrice" />
      <xs:element name="getFlightPriceResponse" type="tns:getFlightPriceResponse" />
      <xs:complexType name="getFlightPrice">
        <xs:sequence>
          <xs:element minOccurs="0" name="from" type="xs:string" />
          <xs:element minOccurs="0" name="to" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="getFlightPriceResponse">
        <xs:sequence>
          <xs:element name="return" type="xs:float" />
        </xs:sequence>
      </xs:complexType>
      <xs:element name="LocationNotFoundException" type="tns:LocationNotFoundException" />
      <xs:complexType name="LocationNotFoundException">
        <xs:sequence />
      </xs:complexType>
    </xs:schema>
  </wsdl:types>
  <wsdl:message name="LocationNotFoundException">
    <wsdl:part element="tns:LocationNotFoundException" name="LocationNotFoundException">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getFlightPrice">
    <wsdl:part element="tns:getFlightPrice" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getFlightPriceResponse">
    <wsdl:part element="tns:getFlightPriceResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="IFlightPriceServiceFacade">
    <wsdl:operation name="getFlightPrice">
      <wsdl:input message="tns:getFlightPrice" name="getFlightPrice">
    </wsdl:input>
      <wsdl:output message="tns:getFlightPriceResponse" name="getFlightPriceResponse">
    </wsdl:output>
      <wsdl:fault message="tns:LocationNotFoundException" name="LocationNotFoundException">
    </wsdl:fault>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="FlightPriceServiceFacadeServiceSoapBinding" type="tns:IFlightPriceServiceFacade">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getFlightPrice">
      <soap:operation soapAction="" style="document" />
      <wsdl:input name="getFlightPrice">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getFlightPriceResponse">
        <soap:body use="literal" />
      </wsdl:output>
      <wsdl:fault name="LocationNotFoundException">
        <soap:fault name="LocationNotFoundException" use="literal" />
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="FlightPriceServiceFacadeService">
    <wsdl:port binding="tns:FlightPriceServiceFacadeServiceSoapBinding" name="FlightPriceServiceFacadePort">
      <soap:address location="http://localhost:8088/external-services-0.0.1-SNAPSHOT/webservices/FlightPriceService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

SOAP Request For Basic Report Using The Omniture

A large deficit in the lack of SDK from the framework SDK OSX WebServicesCore services Web. Because the focus under the terms of the relationship line, at least surprising that any SOAP web services stack frame house. So what is the developer? You must register themselves.


Although the use of more convenient and better than the frames of all, no SOAP interaction with it is not difficult, but it seems the implementation of useful web services: Data Published endpoint via HTTP to a specific URL and removal of applications operating in what is natural.

Here’s a SOAP request for a basic report — an overtime trend of one metric — using the Omniture Web Services API:

<soapenv:Envelope>

<soapenv:Header>

<wsse:Security>

<wsse:UsernameToken>

<wsse:Username>$(ApiUsername)</wsse:Username>

<wsse:Password>$(OneTimeEncryptedPassword)</wsse:Password>

<wsse:Nonce>$(OneTimeNonce)</wsse:Nonce>

<wsu:Created>2009-01-09T18:53:56.545Z</wsu:Created>

</wsse:UsernameToken>

</wsse:Security>

</soapenv:Header>

<soapenv:Body>

<omn:Report.QueueOvertime>

<reportDescription xsi:type=“omn:reportDescription”>

<reportSuiteID xsi:type=“xsd:string”>$(ReportSuiteId)</reportSuiteID>

<date xsi:type=“xsd:string”>2008-11</date>

<dateGranularity>day</dateGranularity>

<metrics soapenc:arrayType=“omn:reportDefinitionMetric[]” xsi:type=“soapenc:Array”>

<item>

<id>pageviews</id>

</item>

</metrics>

</reportDescription>

</omn:Report.QueueOvertime>

</soapenv:Body>

</soapenv:Envelope>

This chunk of XML is POSTed to our SOAP endpoint, https://api.omniture.com/admin/1.2/. The response returned looks something like the following:

<?xml version=“1.0” encoding=“UTF-8”?>

<SOAP-ENV:Envelope>

<SOAP-ENV:Body>

<ns1:<eport.queueovertimeresponse></eport.queueovertimeresponse

<return xsi:type=”tns:reportQueueResponse”>

<status xsi:type=“xsd:string”>queued</status>

<statusMsg xsi:type=“xsd:string”>Your report has been queued</statusMsg>

<reportID xsi:type=“xsd:int”>1313624</reportID>

</return>

</ns1:Report.QueueOvertimeResponse>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

Creating and Parsing a SOAP request on the iPhone

To get this request to work in an iPhone application, we need to do the following:

  1. Create the SOAP header, complete with valid authentication credentials
    1. Encrypt your Omniture api username and secret.
    2. Use [NSString stringWithFormat:@"..."] to create the XML for our SOAP request.
  2. Package the SOAP header from (1), along with a SOAP Body, into a SOAP envelope.
  3. POST the SOAP envelope to the Omniture Web Service endpoint.
  4. Store the results and parse them using libxml.

Authentication Credentials

The following code snippet creates a valid SOAP header in Objective-C:

/** Returns a SOAP Header that complies to the OASIS UsernameToken profile specification
 */
- (NSString*) createSoapHeader {
    NSString* formatString = @"...use the header sample provided earlier...";
    //nonce
    srand(time(NULL));
    int n = rand();
    NSString* nonce = [[NSString stringWithFormat:@"%i", n] md5HexHash];
    //binary version for base64 encoding
    NSData* nonceBinary = [nonce dataUsingEncoding:NSUTF8StringEncoding];
    //date
    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    NSString* created = [formatter stringFromDate:[[NSDate date] 
                                                    dateWithCalendarFormat:nil 
                                                    timeZone:[NSTimeZone 
                                                        timeZoneForSecondsFromGMT:0]]];
    [formatter release];
    // digest = base64(sha1(base64_decode(nonce)+created+secret))
    NSString* digest_concat = [NSString stringWithFormat:@"%@%@%@", 
                                            nonce, created, 
                                            @"YOUR_API_SECRET_THAT_YOU_NEVER_SHARE"];
    NSString* digest = [[[digest_concat dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO] 
                          sha1Hash] 
                        base64Encoding];
    return [NSString stringWithFormat:formatString, 
            [user username], 
            digest, 
            [nonceBinary base64Encoding], 
            created];