Home > Articles

Using an RPC-style SOAP-Based Web Service

SOAP grew out of an effort to create an XML-based method invocation mechanism for distributed objects (primarily Microsoft's DCOM). As such, it is an ideal transport for method calls made over Web Services.

RPC-Oriented Web Services

Remote Procedure Calls (RPCs) made over Web-based protocols are essentially no different from those made over other protocols, such as IIOP, DCOM, or JRMP. The calls are usually synchronous (in other words, the client waits for the method to return before continuing). Zero or more parameters of varying types are passed into the call to provide information to process, and zero or more return values are generated to deliver the outputs of the remote method to the client. The remote method calls are delivered to some form of dispatcher at the remote server that determines which method should be called and arranges for the smooth flow of parameters and return values.

For RPC-style operation, SOAP implementations conform to the preceding description. The difference with SOAP (and other Web-based RPC mechanisms, such as XML-RPC) is that it uses standard, general-purpose transports, such as HTTP, together with a text-based method call description in XML. All of the parameters and return values are encoded in XML as part of the SOAP body, while information about the service and method to call are provided in the transport header and possibly the SOAP header. When sent over HTTP, the SOAP header and body are wrapped in another XML document—the SOAP envelope—and this envelope forms the body of an HTTP POST request.

An HTTP-based SOAP message will be delivered to a SOAP router that takes the form of an HTTP servlet (for a Java implementation). The SOAP router will examine the HTTP and SOAP header information and decide how it should forward the message body. This will involve instantiating or calling a particular component or class that will receive the message. The SOAP router, or its helper classes, will also perform the conversion of the XML-based parameters into Java objects and primitives that can be passed as part of the service invocation. Figure 20.5 shows the operation of such a SOAP router. Note that the description of the Web Service is used by both the client and server to help determine the correct mapping between Java and XML for method calls and parameter types.

This is all good, but why go to this effort? Why not use an existing RPC mechanism, such as RMI or just use HTTP itself?

The justification for not using RMI or CORBA relates to commonality and security. There are at least three different distributed object protocols (CORBA, RMI, and DCOM), each of which has its adherents. The use of HTTP and XML provides a common protocol that is not tied to any vendor. Also, the protocols listed have great difficulty in penetrating most firewalls (not surprising, given their ability to invoke random functionality). However, HTTP (and SMTP) have general right of access through most firewalls, which makes it easier to integrate applications across organizational boundaries (after the security questions are sorted out).

Figure 20.5 A Java-based SOAP router.

CAUTION

From a developer's perspective, one of SOAP's greatest assets is its ability to penetrate firewalls. However, from an administrator's point of view, this presents the same types of problem as traditional RPC, namely the ability to target a random function call at an exposed server. Although the principle of SOAP is only a small step on from the invocation of server-side functionality such as CGI, great care should be taken to ensure adequate security when exposing Web Services. The overall security story for Web Services is still a work in progress.

Although raw HTTP is a good transport, it was created to exchange simple HTML messages. This does not provide the sophistication required for a distributed invocation environment. The use of a defined XML message format brings structure to this environment and allows for the interoperability of Web Service clients and servers from different vendors—something that escaped CORBA until comparatively recently.

Now that you understand the architecture and motivation for RPC-style Web Services, you can install a Java-based Web Service environment and, through it, use and build your own Web Services.

Setting up Axis under Tomcat 4.0

The environment you will use for Web Service development in the first instance consists of the Tomcat servlet engine and the Axis Web Service toolkit, both from the Apache Software Foundation.

You can download Tomcat 4.0 from the Apache Software Foundation at http://jakarta.apache.org/tomcat/ or install it from the CD-ROM as follows:

  1. Unzip the Tomcat 4.0 archive (jakarta-tomcat-4.0.1.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\jakarta-tomcat-4.0.1).

  2. In your personal or system environment, set the environment variable CATALINA_HOME to point to this directory.

You can download Axis from the Apache Software Foundation or install it from the CD-ROM as follows:

  • Unzip the Axis archive (xml-axis-alpha2-bin.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\axis-1_0).

  • Copy the webapps\axis directory from the axis-1_0 distribution into Tomcat's webapps directory ({CATALINA_HOME}\webapps).

You need to install XML support for Axis from the Fall 01 JAX Pack (available from Sun or on the CD-ROM) as follows:

  • Unzip the JAX Pack archive (java_xml_pack-fall01.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\java_xml_pack-fall01).

  • Copy crimson.jar and xalan.jar from the jaxp-1.1.3 directory into axis\WEB-INF\lib under Tomcat's webapps directory ({CATALINA_HOME}\webapps).

Tomcat and Axis are now installed with the appropriate XML support.

In the next section, you will create a client for a simple hello Web Service. First, you must install and test this simple Web Service as follows:

  1. Install the class required for the HelloService by copying the webservices directory from the CD-ROM directory Day20\examples\HelloService to axis\WEB-INF\classes under Tomcat's webapps directory ({CATALINA_HOME}\webapps).

  2. Start Tomcat by running the startup script/batch file in the {CATALINA_HOME}\bin directory.

  3. To ensure that Tomcat and Axis are installed correctly, start a Web browser and point it at http://localhost:8080/axis/index.html. You should see a welcome screen from Axis.

  4. Now deploy the hello server using the deployit batch file in the CD-ROM directory Day20\examples\HelloService.

Assuming that you had no errors, you have now deployed a simple Web Service called MyHelloService. In the long and distinguished tradition of curly-bracket-based languages, you will start with a variation on the Hello World! program.

Service Description Information

Your Web server now has a Web Service installed under it. The next step is to access that Web Service. However, before you can take advantage of the Web Service, you need the following information:

  • A definition of the service you are calling—This information corresponds to the traditional interface definition for an RPC or RMI server. The interface definition contains information about the methods available, the number and types of parameters, the type of any return values, and definitions of any complex types used as parameters.

  • The location of the service—This corresponds to the binding information used by RPC and RMI servers. This Web Service binding information lists the protocols over which you can call the available Web Service methods. For each supported protocol, there is also a URL indicating the location of a server that provides an implementation of that service for that protocol.

As you may have surmised by now, all of this information is provided by a WSDL description of the service.

Anatomy of a WSDL Document

The WSDL for MyHelloService is shown in Listing 20.1. It is worth taking a few moments to study this information because it provides a good insight into the way that Web Services work.

Listing 20.1 WSDL for the Hello Service (MyHelloService.wsdl)

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: 
 3: <definitions
 4:  targetNamespace="http://localhost:8080/axis/services/MyHelloService"
 5:  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 6:  xmlns:serviceNS="http://localhost:8080/axis/services/MyHelloService"
 7:  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 8:  xmlns="http://schemas.xmlsoap.org/wsdl/">
 9: 
 10:  <message name="sayHelloToRequest">
 11:   <part name="arg0" type="xsd:string"/>
 12:  </message>
 13: 
 14:  <message name="sayHelloToResponse">
 15:   <part name="sayHelloToResult" type="xsd:string"/>
 16:  </message>
 17: 
 18:  <portType name="HelloServerPortType">
 19:   <operation name="sayHelloTo">
 20:    <input message="serviceNS:sayHelloToRequest"/>
 21:    <output message="serviceNS:sayHelloToResponse"/>
 22:   </operation>
 23:  </portType>
 24: 
 25:  <binding name="HelloServerSoapBinding"
    type="serviceNS:HelloServerPortType">
 26:   <soap:binding style="rpc"
       transport="http://schemas.xmlsoap.org/soap/http"/>
 27:   <operation name="sayHelloTo">
 28:    <soap:operation soapAction="" style="rpc"/>
 29:    <input>
 30:     <soap:body use="encoded"
 31:         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
 32:         namespace="MyHelloService"/>
 33:    </input>
 34:    <output>
 35:     <soap:body use="encoded"
 36:         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
 37:         namespace="MyHelloService"/>
 38:    </output>
 39:   </operation>
 40:  </binding>
 41: 
 42:  <service name="HelloServer">
 43:   <port name="HelloServerPort"
   binding="serviceNS:HelloServerSoapBinding">
 44:    <soap:address
   location="http://localhost:8080/axis/services/MyHelloService"/>
 45:   </port>
 46:  </service>
 47: 
 48: </definitions>

The document consists of the following sections:

  • The XML prolog and root element (lines 1–8 and 48). The namespace declarations on the root element (definitions) show that all unqualified elements and attributes come from the WSDL schema. The soap prefix denotes types from the SOAP schema, while the xsd prefix denotes types from the W3C XML Schema definition. There is also a namespace defined for this service that is associated with the serviceNS prefix.

  • WSDL message definitions (lines 10–16). These define two matched messages—a request and a response. The request (sayHelloToRequest) takes a single string parameter and the response (sayHelloToResponse) also returns a single string.

  • WSDL portType definitions (lines 18–23). A portType is the equivalent if an interface definition. It contains one or more operation definitions, which in turn are built from the message definitions in the document. In this case, there is a single operation defined in the HelloServerPortType called sayHelloTo. This consists of the two messages, sayHelloToRequest and sayHelloToResponse, seen earlier.

  • Now that you have an interface (portType), you can define the protocols over which that interface can be accessed. The binding element (lines 25–40) creates a binding, called HelloServerSoapBinding, between the HelloServerPortType and SOAP. Within this WSDL binding, a SOAP binding (soap:binding) is defined. Because SOAP can work with a variety of underlying transports and it can work in an RPC-centric or document-centric way, the attributes on the soap:binding indicate that it is an RPC-style binding that uses HTTP.

  • The WSDL operation is then mapped to a SOAP operation with input and output soap:body elements defined to map the request and response.

  • Finally, an instance of the service is defined in the WSDL service element (lines 42–46). A WSDL service contains a list of WSDL port elements. Each port element defines a specific instance of a server that conforms to one of the WSDL bindings defined earlier.

  • Again, in the case of the simple Hello service, the service element (named HelloServer) contains a single WSDL port called HelloServerPort. This specifies that a server conforming to the HelloServerSoapBinding can be found at the given SOAP address, namely http://localhost:8080/axis/service/MyHelloService.

This is a very simple WSDL document defining a very simple service. WSDL documents are typically far longer and more complex. Because of this, WSDL is largely intended for manipulation by tools and applications.

Creating a Java Proxy from WSDL

Given the service description in Listing 20.1, the next step is to create a client that can use this service. The simplest way to do this is to have a tool generate a proxy for the service. This proxy will be a local object that will hide away a lot of the complexity associated with the mechanics of calling methods on the service.

You can apply the Apache Axis Wsdl2java tool to MyHelloService.wsdl as follows

java org.apache.axis.wsdl.Wsdl2java MyHelloService.wsdl

NOTE

To run the tools and compile the files, you must have the JAR files from the axis\WEB-INF\lib directory on your classpath, namely axis.jar, clutil.jar, crimson.jar, log4j-core.jar, wsdl4j.jar, and xalan.jar.

This will generate three Java files:

  • HelloServerPortType.java is a Java interface that represents the remote interface (or portType in WSDL terms). This is shown in Listing 20.2. Note that the interface looks like an RMI interface in that it extends java.rmi.Remote, and the method is defined as throwing java.rmi.RemoteException. The service proxy implements this interface, and the client should use the interface type to reference instances of the service proxy.

  • HelloServer.java is a factory class that creates instances of the service proxy. This is shown in Listing 20.3. The client instantiates a factory and then calls the getHelloServerPort method to obtain a service proxy. Two forms of this method are provided—one that allows the client to specify the endpoint at which the service resides and the other that takes no arguments. The latter method will use the location information contained in the WSDL file when instantiating the service proxy.

  • HelloServerSoapBindingStub.java is the service proxy itself. Note that by using a separate interface to represent the portType and a factory for the creation of the proxy, the same client code can be used, regardless of the particular protocol binding. The code for HelloServerSoapBindingStub.java is not shown here because it is very similar to the "raw" SOAP code you will see shortly.

Listing 20.2 HelloServerPortType.java

 1: /**
 2: * HelloServerPortType.java
 3: *
 4: * This file was auto-generated from WSDL
 5: * by the Apache Axis Wsdl2java emitter.
 6: */
 7:  7:
 8: public interface HelloServerPortType extends java.rmi.Remote {
 9:   public String sayHelloTo(String arg0) throws java.rmi.RemoteException;
 10: }

Listing 20.3 HelloServer.java

 1: /**
 2: * HelloServer.java
 3: *
 4: * This file was auto-generated from WSDL
 5: * by the Apache Axis Wsdl2java emitter.
 6: */
 7: 
 8: public class HelloServer {
 9: 
 10:   // Use to get a proxy class for HelloServerPort
 11:   private final java.lang.String HelloServerPort_address =
 12:           "http://localhost:8080/axis/services/MyHelloService";
 13:   public HelloServerPortType getHelloServerPort() {
 14:    java.net.URL endpoint;
 15:     try {
 16:       endpoint = new java.net.URL(HelloServerPort_address);
 17:     }
 18:     catch (java.net.MalformedURLException e) {
 19:       return null; // unlikely as URL was validated in wsdl2java
 20:     }
 21:     return getHelloServerPort(endpoint);
 22:   }
 23: 
 24:   public HelloServerPortType
            getHelloServerPort(java.net.URL portAddress) {
 25:     try {
 26:       return new HelloServerSoapBindingStub(portAddress);
 27:     }
 28:     catch (org.apache.axis.SerializationException e) {
 29:       return null; // ???
 30:     }
 31:   }
 32: }

You can now write a client application that uses these classes. The code for such an application is shown in Listing 20.4. This application simply takes the name passed as a parameter and sends it to the sayHelloTo method of the Web Service. You can see the creation of the HelloServer service proxy factory on line 20. The client then calls the getHelloServerPort method to obtain an instance of the service proxy (line 23). The client can then call the sayHelloTo method passing the given parameter (line 28). This method invocation is wrapped in a try-catch block to catch any potential RemoteException that may occur.

Listing 20.4 HelloServerClient.java Application That Uses Generated Service Proxy

 1: import java.rmi.RemoteException;
 2: 
 3: public class HelloServerClient
 4: {
 5:  public static void main(String [] args)
 6:  {
 7:   String name = "unknown";
 8:   
 9:   if (args.length != 1)
 10:   {
 11:     System.out.println("Usage: WebServiceSayHello <name>");
 12:     System.exit(1);
 13:   }
 14:   else
 15:   {
 16:     name = args[0];
 17:   }
 18: 
 19:   // Instantiate the factory
 20:   HelloServer factory = new HelloServer();
 21: 
 22:   // Get a PortType that represents this particular service
 23:   HelloServerPortType service = factory.getHelloServerPort();
 24: 
 25:   try
 26:   {
 27:    // Call the service
 28:    String response = service.sayHelloTo(name);
 29:   
 30:    System.out.println(response);
 31:   }
 32:   catch(RemoteException ex)
 33:   {
 34:    System.out.println("Remote exception: " + ex);
 35:   }
 36:  }
 37: }

To test out your client, you should:

  1. Compile the client code.

  2. Ensure that the service is running (both Tomcat and the Axis server).

  3. Run the client (with the appropriate classpath settings) as shown

  4. prompt> java HelloServerClient Fred
    Hello Fred!

Calling the Web Service Through SOAP

You have now accessed the service through a service proxy based on WSDL. However, you can access the service directly through SOAP, should that be necessary. Indeed, some older toolkits may only provide a SOAP-level API and no WSDL-based tools, so this section looks quickly at how you would achieve the same effect directly with SOAP.

Listing 20.5 shows the code you would write under Apache SOAP 2.2 (the precursor to Axis) to call the Hello service using the SOAP API directly.

Listing 20.5 SoapSayHello.java Using the Apache SOAP 2.2 API

 1: import java.net.*;
 2: import java.util.*;
 3: import org.apache.soap.*;
 4: import org.apache.soap.rpc.*;
 5: 
 6: public class SoapSayHello
 7: {
 8:  private static String serviceUrn = "MyHelloService";
 9:  private static String soapRouterUrl =
          "http://localhost:8080/axis/servlet/AxisServlet";
 10:  
 11:  public static void main(String[] args)
 12:  {
 13:   String name = "unknown";
 14:   
 15:   if (args.length != 1)
 16:   {
 17:     System.out.println("Usage: SoapSayHello <name>");
 18:     System.exit(1);
 19:   }
 20:   else
 21:   {
 22:     name = args[0];
 23:   }
 24: 
 25:   URL url = null;
 26:   
 27:   try
 28:   {
 29:    url = new URL(soapRouterUrl);
 30:   }
 31:   catch (MalformedURLException ex)
 32:   {
 33:    System.out.println("Exception: " + ex);
 34:    System.exit(1);
 35:   }
 36:   
 37:   Call call = new Call();
 38: 
 39:   call.setTargetObjectURI(serviceUrn);
 40:   call.setMethodName("sayHelloTo");
 41: 
 42:   Vector params = new Vector();
 43: 
 44:   params.addElement(new Parameter("name", String.class,
 45:                   name, Constants.NS_URI_SOAP_ENC));
 46:   call.setParams(params);
 47: 
 48:   Response response;
 49: 
 50:   try
 51:   {
 52:    response = call.invoke(url, "");
 53:   }
 54:   catch (SOAPException e)
 55:   {
 56:    System.err.println("Caught SOAPException (" +
 57:             e.getFaultCode() + "): " +
 58:             e.getMessage());
 59:    return;
 60:   }
 61: 
 62:   if (!response.generatedFault())
 63:   {
 64:    Parameter retVal = response.getReturnValue();
 65:    Object value = retVal.getValue();
 66: 
 67:    System.out.println(value != null ? "\n" + value : "I don't know.");
 68:   }
 69:   else
 70:   {
 71:    Fault fault = response.getFault();
 72: 
 73:    System.err.println("Generated fault: ");
 74:    System.out.println (" Fault Code  = " + fault.getFaultCode()); 
 75:    System.out.println (" Fault String = " + fault.getFaultString());
 76:   }
 77:  }
 78: }

The first thing to notice is that the endpoint URL is now split into the service name and the SOAP router (lines 8 and 9). This SOAP router URL must be turned into a java.net.URL (lines 25–35) for it to be used.

A SOAP Call is then instantiated (line 37) and populated with the service name (line 39) and the method name (line 40). The parameters for the call must be encoded as Parameter instances, specifying the parameter name, Java class, and encoding required. A java.util.Vector containing all of the parameters is then passed to the Call object (lines 42–46).

The call is then made to the SOAP server using the invoke method (line 52). This is where the SOAP router URL is passed in. A SOAP Response is returned from invoke.

Now the result must be deciphered (lines 62–76). This involves checking for an error, retrieving the Parameter object, extracting the actual returned object from it, and then casting this returned object to the appropriate type.

As you can see, the use of a proxy is preferable because it removes most of the complexity. This is why the Java APIs for creating and sending SOAP messages—JAX-RPC and JAXM—both work at a higher level than this. The benefits of using the WSDL-based proxy are that the client code is less complex, there is type safety by using the generated Java interface, and the client developer needs to know very little about the SOAP-level operations or indeed about SOAP itself.

A Half-Way House

There is a compromise that can be made between service-specific calling using a proxy and the use of raw SOAP. Axis provides a ServiceClient class that performs much of the code shown in Listing 20.5. In fact, all of the code from line 25 on can be effectively replaced by the following lines:

ServiceClient client = new ServiceClient(soapRouterUrl);
      
String response = (String)client.invoke(serviceUrn,
                    "sayHelloTo",
                    new Object [] { name });

The service address, method name, and the parameters are all passed into the invoke method. Note that the last argument in the code shown creates a new array of type Object and populates it with a single element, which is the String containing the name provided by the user.

In this case, there is a lot more flexibility than with the WSDL proxy, because the method name and parameter can be specified at runtime. This allows for dynamic interaction with discovered services. However, the code shown is preferable to the SOAP code in Listing 20.5 because the code surrounding the call setup has been largely simplified.

Dynamic calling will be examined further tomorrow in the discussion surrounding the use of directory services.

Debugging a SOAP Interaction

As with any distributed environment, debugging Web Service interaction is a challenge. One of the main issues is knowing precisely what is being sent and received. To assist with this, Axis provides a tool called tcpmon that will monitor and display SOAP traffic.

The basic idea is that you target your client at a different port. The tcpmon utility listens on that port, logs the SOAP traffic arriving, and then passes it on to the real SOAP server port. SOAP traffic sent back is also logged. If you cannot change the client configuration, you could change the port on which the SOAP server listens. The tcpmon utility can then listen on the original SOAP server port and forward traffic on to the new port. Figure 20.6 shows how an instance of tcpmon can monitor inbound traffic from SOAP clients on port 8888, log the traffic, and then forward it on to the real SOAP router listening on port 8080.

Figure 20.6 The tcpmon utility monitoring SOAP calls on port 8888 and passing them on to the real SOAP router on port 8080.

To start the tcpmon utility, type

java org.apache.axis.utils.tcpmon

This will start a GUI through which the traffic will be displayed. When the GUI starts up, you will be prompted for the port on which to listen and also the port and host to which traffic should be forwarded. Figure 20.7 shows a monitor session being started that will listen on port 8888 and forward all traffic received on to localhost:8080.

TIP

The tcpmon utility allows you to set up multiple port/host/port mappings. Each will be displayed in its own tabbed pane.

Figure 20.7 Setting up the port configuration for tcpmon.

The request and response messages are displayed as pairs, as shown in Figure 20.8. This shows an interaction between the Hello service and a client that has been modified so that its target port is configurable. The client sends its request to port 8888 with a SOAPAction of MyHelloService/sayHelloTo. You can see the method invocation and the string parameter in the SOAP body. The response is shown in the right pane. In the response, the SOAP body contains a sayHelloToResponse message encapsulating the sayHelloToResult return value.

Figure 20.8 SOAP request and response to the Hello service seen through tcpmon.

The tcpmon utility will retain a history of messages sent back and forth through a particular port. You can then look back through a sequence of messages in your own time.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020