Service-Oriented Architecture and Web Services: Concepts, Technologies, and Tools

   
By Ed Ort, April 2005  

Introduction | Terms and Concepts | Web Services Protocols and Technologies | Java Developer Tools and Servers for Web Services

Java Technologies for Web Services

Although web services are designed to be language and platform neutral, the Java programming language is ideal for developing web services and applications that use web services. The portability and interoperability of applications written in the Java programming language mesh well with the objective of web service interoperability. A core set of Java technologies for web services is integrated into the Java 2 Platform, Enterprise Edition (J2EE) 1.4 platform. These technologies are designed for use with XML, and conform to web services standards such as SOAP, WSDL, and UDDI. You can take advantage of the technologies by developing and deploying web services and applications to the J2EE 1.4 platform. (In addition, the J2EE 1.4 platform also offers a wide variety of enterprise application features such as resource pooling and transaction management.) Implementations of the Java technologies for web services are available in the J2EE 1.4 SDK and Sun Java Application Server 8.1. The J2EE 1.4 SDK and Sun Java Application Server 8.1 are available as a single, "all-in-one" bundle, or available separately.

 

The Java programming language is ideal for developing web services and applications that use web services.


Supplementing J2EE 1.4 is the Java Web Services Developer Pack (Java WSDP) 1.5, which provides implementations of additional Java technologies for web services as well as updates to the web service technology implementations in the J2EE 1.4 SDK and Sun Java Application Server 8.1.

This section briefly describes the Java technologies for web services and their implementations in J2EE 1.4 and Java WSDP 1.5.

Web Services Technologies in J2EE 1.4

The Java technologies for web services in the J2EE 1.4 platform are:

Java API for XML Processing (JAXP) 1.2

Java API for XML Processing (JAXP) is a Java API for processing XML documents. Using JAXP, you can invoke a SAX or DOM parser in an application to parse an XML document. A parser is a program that scans the XML document and logically breaks it up into discrete pieces. It also checks that the content is well-formed. Some parsers also validate an XML document against an associated XML Document Type Definition (DTD) or XML schema. The parsed content is then made available to the application. Recall that XML has been generally adopted as the data language for web services. It's the language that's used in documents that are exchanged between clients and web services. So an XML parser, a program that essentially feeds the contents of an XML document to an application, is an important part of a web services-based SOA. The primary functional addition in JAXP 1.2 over previous JAXP releases is support for W3C XML Schema.

Simple API for XML Parsing (SAX) and Document Object Model (DOM) are parsing standards, and are the most frequently used approaches to parsing XML documents. In the SAX approach, the parser starts at the beginning of the document and passes each piece of the document to the application in the sequence it finds it. Nothing is saved in memory. The application can take action on the data as it gets it from the parser, but it can't do any in-memory manipulation of the data. For example, it can't update the data in memory and return the updated data to the XML file. In the DOM approach, the parser creates a tree of objects that represents the content and organization of data in the document. In this case, the tree exists in memory. The application can then navigate through the tree to access the data it needs, and if appropriate, manipulate it.

Here is a simple example that illustrates how JAXP is used to invoke a SAX parser:

 

import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;

public class SAXRead
    extends DefaultHandler {

    public void ParseSAX() {

        // Create a SAX Parser Factory instance
        SAXParserFactory spf = SAXParserFactory.newInstance();

        // Turn on validation and namespace awareness
        spf.setValidating(true);
        spf.setNamespaceAware(true);

        // Create a SAXParser instance
        SAXParser saxParser = spf.newSAXParser();

        // Get an XMLReader
        xmlReader = saxParser.getXMLReader();

        // Set the ContentHandler of the XMLReader
        xmlReader.setContentHandler(this);

        // Parse the XML document
        xmlReader.parse(XMLDocumentName);
        }
}


First, an instance of the SAXParserFactory class is used to generate an instance of a SAXParser class. This is the SAX parser. Next, the SAXParser class is used to get an XML reader that implements the XMLReader interface. The parser must implement this interface. The parser (through the XMLReader interface) reads the XML document. Notice that the XMLReader implementation is also used to set a content handler that does any parsing-related processing. The content handler part of the application would define methods to be notified by the parser when the parser encounters something significant (in SAX terms, an "event") such as the start of an XML tag, or the text inside of a tag. These methods, known as callback methods, take any subsequent actions based on the event.

Also notice that the SAXParserFactory can be configured to set various parser characteristics. In this example, validation and namespace awareness are turned on. This means that the parser will verify that the contents of the XML document conforms to the associated schema, and that the parser will be aware of namespaces.

Here is a simple example that illustrates how JAXP is used to invoke a DOM parser:

 

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;

public class DOMRead {

    public void parseDOM() {

        // Create a DocumentBuilderFactory instance
        DocumentBuilderFactory dbf =
           DocumentBuilderFactory.newInstance();

        // Turn on validation and namespace awareness
        dbf.setValidating(true);
        dbf.setNamespaceAware(true);

        // Create a DocumentBuilder instance
        db = dbf.newDocumentBuilder();

        // Parse the input file
        Document doc = db.parse(XMLDocumentFile);

        // Parse the tree
        }
}


As in SAX parsing, a factory is used to create an instance of a DOM parser. However, unlike SAX parsing, DOM parsing does not use a content handler or callback methods. The parse method of the DocumentBuilder instance returns a Document object that represents the entire XML document as a tree. The application must then explicitly traverse the tree and process what it finds.

JAXP comes with its own parser. (The J2EE 1.4 SDK implementation of JAXP 1.2 uses Xerces 2 as the default parser.) However the API is designed to allow any parser to be plugged in and used (provided that the parser conforms to the API).

In addition to its features for invoking parsers, JAXP can be used to transform XML documents (for example, to HTML) in conformance with the XSL Transformations (XSLT) specification. The J2EE 1.4 SDK implementation of JAXP 1.2 includes an XSLT stylesheet compiler called XSLTC.

Java API for XML-based RPC (JAX-RPC) 1.1

Java API for XML-Based RPC (JAX-RPC) is a Java API for accessing services through XML (SOAP-based) RPC calls. The API incorporates XML-based RPC functionality according to the SOAP 1.1 specification. JAX-RPC allows a Java-based client to call web service methods in a distributed environment, for example, where the client and the web service are on different systems. From an application developer's point of view, JAX-RPC provides a way to call a web service. From a service developer's point of view, it provides a way to make a web service available so that it can be called from an application. Although JAX-RPC is a Java API, it doesn't limit the client and the web service to both be deployed on a Java platform. A Java-based client can use JAX-RPC to make SOAP-based RPC calls to web service methods on a non-Java platform. A client on a non-Java platform can access methods in a JAX-RPC enabled web service on a Java platform.

JAX-RPC is designed to hide the complexity of SOAP. When you use JAX-RPC to make an RPC call, you don't explicitly code a SOAP message. Instead you code the call in the Java programming language, using the Java API. JAX-RPC converts the RPC call to a SOAP message and then transports the SOAP message to the server. JAX-RPC on the server converts the SOAP message and then calls the web service. Then the sequence is reversed. The web service returns the response. JAX-RPC on the server converts the response to a SOAP message, which is then transported back to the client. JAX-RPC on the client converts the SOAP message and then returns the response to the application.

To make a web service available to clients through JAX-RPC, you need to provide a JAX-RPC service endpoint definition. This involves defining two Java classes for each endpoint: one that defines the JAX-RPC service endpoint interface (which identifies the remote methods that can be called by the client), and the other that implements the interface. The JAX-RPC specification defines the mapping between the definition of a JAX-RPC service endpoint and a WSDL service description. In fact, all JAX-RPC implementations must be able to produce a WSDL document from a service endpoint definition. However the mapping also makes it possible for an implementation to do the reverse -- produce a JAX-RPC service endpoint definition from a WSDL document. The J2EE 1.4 SDK provides a mapping tool, called wscompile. You can use a mapping tool such as wscompile to generate a WSDL file from a JAX-RPC service endpoint definition, or a JAX-RPC service endpoint definition from a WSDL file. The latter ability is important for web services that are not on a Java platform.

Here's an example of a JAX-RPC service endpoint definition for a web service that returns stock quotes. First, here's the JAX-RPC service endpoint interface:

 

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface StockQuoteProvider extends Remote {

public float getLastTradePrice(String tickerSymbol)
                                throws RemoteException;
}


Next, the implementation class:

 

import java.xml.rpc.server.ServiceLifecycle;

public class StockQuoteService implements
               StockQuoteProvider, ServiceLifecycle {

public float getLastTradePrice(String tickerSymbol)
    {
      // Code for the method
          ...
    }

}


wscompile

JAX-RPC provides a lot of flexibility in the way a client can invoke a method on a web service. The client can invoke the remote method through a local object called a stub (this is one of the artifacts generated by wscompile). Alternatively, the client can use a dynamic proxy to invoke the method. Or the client can dynamically invoke the method using the JAX-RPC Dynamic Invocation Interface (DII). Stubs are used when a JAX-RPC client knows what method to call and how to call it (for example, what parameters to pass). A dynamic proxy is a class that dynamically supports service endpoints at runtime, without the need to generate stubs. DII gives a client a way to invoke a remote method dynamically, for example, when a client doesn't know the remote method name or its signature until run time.

Invoking a remote method through a stub is like invoking a remote method using Java Remote Method Invocation (RMI). As is the case for RMI, in JAX-RPC, a stub is designed to simplify remote method calls, that is, by making them appear like local method calls. A local stub object is used to represent a remote object. To make a remote method call, all a JAX-RPC client needs to do is make the method call on the local stub. The stub (using the underlying runtime environment) then formats the method call and directs it to the server -- this process is called marshalling. On the server, a class called a tie (also called a skeleton) unmarshals this information and makes the call on the remote object. The process is then reversed for returning information to the client.

Here, for example, is part of what the code might look like for a client class that uses a stub to invoke the getLastTradePrice method in the stock quote web service:

 

public class SqpClient {
    public static void main(String[] args) {
        StockQuoteProvider_Stub sqp =
           (StockQuoteProvider_Stub)(
            new StockQuoteService_Impl().getStockQuoteProviderPort());
        sqp._setProperty(
            Stub.ENDPOINT_ADDRESS_PROPERTY,
               "java:comp/env/service/StockQuoteService")
        float quote = sqp.getLastTradePrice(
               "ACME");

        }
}


SOAP with Attachments API for Java (SAAJ) 1.2

SOAP with Attachments (SAAJ) is another API (that is, in addition to JAX-RPC) for creating and sending SOAP messages. In fact, SAAJ is used, "under the covers," by other Java for XML APIs, such as JAX-RPC and JAXR, to create and send SOAP messages. The SAAJ API 1.2 conforms to the SOAP 1.1 specification and the SOAP with Attachments specification. This means that you can use SAAJ to create and send SOAP message with or without attachments.

To create a SOAP message using SAAJ for sending to a web service, a client gets a connection to the service, creates a message, adds content to the message, and then adds attachments (if any).

Here's an example that illustrates the steps:

 

import javax.xml.soap.*;

// Get a connection
SOAPConnection conn;
SOAPConnectionFactory scf =
        SOAPConnectionFactory.newInstance();
conn = scf.createConnection();

// Create a message
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage msg = mf.createMessage();

// Add content to the message
SOAPPart sp = msg.getSOAPPart() ;
SOAPEnvelope envelope = sp.getEnvelope();
SOAPHeader hdr = envelope.getHeader();
SOAPBody bdy = envelope.getBody();
SOAPBodyElement sbe = bdy.addBodyElement
  (envelope.createName("GetBookDetails", "bp",
                  "http://www.bookprovider.com"));
sbe.addChildElement( envelope.createName(
                           "searchCriteria", "bp",
  "http://www.bookprovider.com" )).addTextNode("author");
sbe.addChildElement( envelope.createName(
                  "searchValue", "bp",
  "http://www.bookprovider.com" )).addTextNode("Hemingway");

// Add attachment
AttachmentPart ap = msg.createAttachmentPart();
byte[] jpegData = "..."
ap.setContent(new ByteArrayInputStream(jpegData), "image/jpeg")
msg.addAttachmentPart(ap);

// Close the connection
connection.close();


Notice that the client constructs the content part-by-part, following the SOAP message structure shown in the earlier discussion of SOAP.

After creating the message, the client can use SAAJ to send the message synchronously (and then wait for a reply), or asynchronously (and continue processing without waiting for a reply). Here's an example of sending the message synchronously:

 

java.net.URL urlendpoint = new URL(
    "http://www.bookstogo.com/bookordering"
SOAPMessage reply = conn.call(message, urlEndpoint)


The web service then processes the message and returns a reply:

 

public SOAPMessage onMessage(SOAPMessage message) {

SOAPEnvelope menv = message.getSOAPPart().getEnvelope();
SOAPBody sb = menv.getBody();
Iterator sbes = sb.getChildElements(menv.createName
   ("GetBookDetails","bp",
   "http://www.bookprovider.com"));
while ( sbes.hasNext() ) {

...


Java API for XML Registries (JAXR) 1.0

Java API for XML Registries (JAXR) is a Java API that you can use to access standard registries such as those that conform to UDDI or ebXML. Using the API, you can register a service in a registry or discover services in a registry. JAXR 1.0 is compatible with UDDI 2 and the ebXML registry specifications. However the JAXR 1.0 implementation in the J2EE 1.4 SDK currently supports access to UDDI 2 registries only. Note though that support for ebXML registries is coming soon -- see The Future: Sun's SOA Initiative.

 
Figure 5: Processing a JAXR Request ( Click image to enlarge)

There are three roles that take part in issuing and handling requests made through the JAXR API: JAXR clients, JAXR providers, and registry providers. The JAXR API provides interfaces and classes for use by JAXR clients and providers. A JAXR provider implements the JAXR API. For example, the implementation of the JAXR API in the J2EE 1.4 SDK is a JAXR provider. A registry provider is an implementation of a registry specification, for instance, an actual UDDI registry.

Here's how the roles interact. A JAXR client uses JAXR interfaces and classes to request access to a registry. The client sends the request to a JAXR provider. When a JAXR provider receives a request from a JAXR client, it transforms the request into an equivalent request that is based on the specifications of the target registry. The JAXR provider then passes this transformed request to a registry provider. The registry provider receives a request from a JAXR provider and processes it.

The process is then reversed. The registry provider returns a response to the JAXR provider, which transforms it to an equivalent JAXR response. The JAXR provider sends the JAXR response to the JAXR client.

Here is part of an example that shows a client using the JAXR API to discover book store services (these are classified in the NAICS classification scheme as code number 451211) in a UDDI registry:

 

import javax.xml.registry.*;
import javax.xml.registry.infomodel.*;
import java.net.*;
import java.util.*;

public class bookstoreQuery {
    Connection connection = null;
    RegistryService rs = null;
    BusinessQueryManager queryManager = null;
    BusinessLifeCycleManager lifeCycleManager = null;
    String queryURL = "some UDDI registry URI";

// Get a connection to the registry.
     bookstoreQuery.query("ntis-gov:naics", "Book Stores", "451211" );

// Define connection configuration properties
     Properties props = new Properties();
     props.setProperty("javax.xml.registry.queryManagerURL", queryURL);
     props.setProperty("javax.xml.registry.factoryClass",
        "com.sun.xml.registry.uddi.ConnectionFactoryImpl");
     factory.setProperties(props);
     connection = factory.createConnection();

// Get registry service and managers
   rs = connection.getRegistryService();
   queryManager = rs.getBusinessQueryManager();
   lifeCycleManager = rs.getBusinessLifeCycleManager();

// Get classification information
   ClassificationScheme classificationScheme =
   queryManager.findClassificationSchemeByName( cName );
   Classification classification =
     lifeCycleManager.createClassification( classificationScheme, keyName, keyValue );
   Collection classifications = new ArrayList();
   classifications.add ( classification );

// Find using the classification information
   BulkResponse response =
   queryManager.findOrganizations(findQualifiers,
     null, classifications, null, null, null);
   Collection orgs = response.getCollection();


Web Services Technologies and Tools in Java WSDP 1.5

Java WSDP is a package that provides early access to the latest technology implementations and tools for web services development. The most current version of the package, Java WSDP 1.5, includes implementations of a number of web services technologies that are not in J2EE 1.4, as well as newer releases of the web services technology implementations that are in the J2EE 1.4 SDK. The implementations of web services technologies that are not in J2EE 1.4 are:

The newer releases of web services technology implementations that are in the J2EE 1.4 SDK are:

In addition to these web services technology implementations, Java WSDP 1.5 also provides an Early Access implementation of the Sun Java Streaming XML Parser (SJSXP), which implements the Streaming API for XML (StAX).

Java Architecture for XML Binding (JAXB) v1.0.4

Java Architecture for XML Binding (JAXB) gives you a way of mapping an XML document into a set of Java classes and interfaces that are based on the document's XML schema. The value of doing that is that your application can work directly with Java content rather than working with XML content (as it would have to using an API such as JAXP).

 

The mapping is done in two steps. First you use a binding compiler provided with the JAXB implementation to bind the document's XML schema into a set of Java classes and interfaces. These classes and interfaces form the core of a binding framework. After compiling the classes and interfaces, you use methods in the binding framework to marshal the XML document into a tree of content objects. You can then access the data in the tree through other methods in the binding framework.

For example, suppose that you had an XML document, books.xml that was associated with a schema, books.xsd. Click here to see the schema. This schema defines a <Collection> as an element that has a complex type. This means that it has child elements, in this case, <book> elements. Each <book> element also has a complex type named bookType. The <book> element has child elements such as <name>, <ISBN>, and <author>. Some of these have their own child elements.

Running the books.xsd schema through the binding compiler generates a set of interfaces and a set of classes that implement the interfaces. Here is the interface the binding compiler generates for the <Collection> element complex type. Here is the generated class that implements the complex type.

To unmarshal an XML document, you:

  • Create a JAXBContext object that provides the entry point to the JAXB API.
  • Create an Unmarshaller object. This object contains methods that perform the actual unmarshalling.
  • Call the unmarshal method to do the unmarshalling.

After unmarshalling, your application can use get methods in the schema-derived classes to access the XML data. Here, for example, is a program that unmarshals the data in the books.xml file and then displays the data. Notice that the program includes the following statement:

 

unmarshaller.setValidating(true);


This validates the source data against the associated schema.

Some other things you can do using JAXB are:

  • Unmarshal XML data from other input sources such as an InputStream object, a URL, or a DOM node.
  • Marshall an XML document from a content tree to an XML file, or to other output formats such as an OutputStream object or a DOM node.
  • Validate the content tree against a schema.

JAXB 1.0.4 supports a subset of the W3C XML Schema (some schema constructs, such as the identity construct, are not supported). In addition, JAXB also unofficially supports the OASIS RelaxNG schema language.

XML and Web Services Security v1.0

XML and Web Services Security (XWS Security) provides message-level security for applications that use JAX-RPC to access web services. Think of message-level security as a way of supplementing the transport-layer security provided by secure Internet transport protocols such as HTTPS. In message-level security, security information is contained in the SOAP message header. One of the primary uses of message-level security is to secure a SOAP message from unauthorized access at intermediate nodes along the message path. Recall that a SOAP message can pass through a set of intermediate nodes as it travels from a client to a service, and that each node can independently process part or all of the message before forwarding it. Using message-level security, you can do things like encrypt a SOAP message and permit decryption only by the target web service (that is, not by any of the intermediate nodes). For example, this could be used to protect credit card information from exposure until it's received by the target service -- perhaps a credit verification service from a credit card company. In addition, XWS security gives you the flexibility of securing different parts of a SOAP message and in different ways. Specifically, you can secure an entire service, one or more service ports, or one or more service operations. For instance, you can encrypt some parts of the message and not other parts, you can sign with a digital signature some parts of the message and not sign others. In addition to including encryption information, the SOAP message header might include other security-related items such as an X.509 certificate or a security token. The SOAP header can also point to a repository of security information for the message.

XWS Security 1.0 implements the following WS-Security standards: SOAP Message Security V1.0, Username Token Profile V1.0, and X.509 Token Profile V1.0 (each of these describes a particular aspect of SOAP message security). XWS Security also implements the following W3C security standards: XML Signature and XML Encryption.

To use XWS Security, you need to create security configuration files for the client and service. A security configuration file is an XML file that describes the security operations to be performed on the SOAP message. For example, here is part of a simple security configuration file for a client that applies an XML Digital Signature to a SOAP message:

 

<xwss:JAXRPCSecurity
  xmlns:xwss="#">
    <xwss:Service>
        <xwss:SecurityConfiguration dumpMessages="true">
          <xwss:Sign>
            <xwss:X509Token
              certificateAlias="xws-security-client"/>
            </xwss:Sign>
            <xwss:RequireSignature/>
        </xwss:SecurityConfiguration>
    </xwss:Service>
    <xwss:SecurityEnvironmentHandler>
        com.sun.xml.wss.sample.SecurityEnvironmentHandler
    </xwss:SecurityEnvironmentHandler>
</xwss:JAXRPCSecurity>


  • The <xwss:JAXRPCSecurity> element identifies this as a security configuration file.
  • The <xwss:SecurityConfiguration> element specifies the security operations to be performed.
  • The <xwss:Sign> element specifies that a digital signature will be applied.
  • The <xwss:X509Token> element specifies an X.509 certificate token that indicates the key used for the digital signature. The digital signature refers to this token.
  • The <xwss:RequireSignature> element specifies that the client expects the response it receives from the service to be signed.
  • The <xwss:SecurityEnvironmentHandler> element specifies a CallbackHandler, a class that gets the security information (such as private keys and certificates) needed for the signing operation.

After the needed security configuration files are created, you invoke the wscompile tool -- the same tool that you use to create a WSDL file and artifacts for a JAX-RPC-based web service. When you run the wscompile tool, you specify the -security option and identify a security configuration file. The tool then generates the artifacts needed for the security operations specified in the configuration file.

XML Digital Signatures v1.0 EA2

XML Digital Signatures v1.0 EA2 is an early access implementation of the Java Digital Signature API. You can use the API to sign the content of an XML document (actually, you can use the API to sign any binary data) in conformance with the W3 standard, XML-Signature Syntax and Processing, and also to validate the signature.

Here is an example that uses the Java Digital Signature API for signing an XML document. The example is adapted from a sample program provided in Java WSDP 1.5 for the Java Digital Signature API. The program uses an XMLSignatureFactory to create the digital signature:

 

XMLSignatureFactory fac =
       XMLSignatureFactory.getInstance("DOM",
       (Provider) Class.forName(providerName).newInstance());


It then creates objects that map to corresponding elements in the XML signature. For example the SignedInfo object corresponds to a <SignedInfo> element in the XML signature. The <SignedInfo> element contains signature information and a reference to the data to be signed.

 

SignedInfo si = fac.newSignedInfo
           (fac.newCanonicalizationMethod
             (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                 null),
            fac.newSignatureMethod(SignatureMethod.DSA_SHA1,
                null),
            Collections.singletonList(ref));


Next, the program creates a 512-bit DSA key and a KeyInfo object that contains the public key to be used in decrypting the signature. Here are the statements that create the DSA key:

 

 KeyPairGenerator kpg =
           KeyPairGenerator.getInstance("DSA");
       kpg.initialize(512);
       KeyPair kp = kpg.generateKeyPair();


The program then creates an instance of the document, generates a digital signature for the document, and puts the digital signature in a file. Here are the statements that generate the digital signature:

 

 DOMSignContext dsc = new DOMSignContext
         (kp.getPrivate(), doc.getDocumentElement());

        XMLSignature signature = fac.newXMLSignature(si, ki);
          signature.sign(dsc);


Java API for XML Processing (JAXP) v1.2.6_01

JAXP 1.2.6_01 is an updated reference implementation of JAXP 1.2. A number of enhancements have been made to the JAXP reference implementation since the release of the JAXP 1.2 implementation in the J2EE 1.4 SDK. These include new releases of the Xerces parser, and new security-related properties -- for example, you can specify that the parser not allow a specific DTD. The JAXP v1.2.6_01 implementation in Java WSDP 1.5 includes a new version of the Xerces parser (v2.6.2) and a new version of the Xalan transformer (v2.6.0).

Java API for XML-based RPC (JAX-RPC) v1.1.2_01

JAX-RPC 1.1.2_01 is an updated reference implementation of JAX-RPC 1.1. The major enhancement in JAX-RPC 1.1.2_01 is support for WS-I Basic Profile 1.1. Recall that the WS-I Basic Profile identifies a core set of web services technologies, that when implemented in different platforms, helps ensure interoperability of web services across those platforms. WS-Basic Profile 1.1 adds a number of technologies to the core set, including SOAP Messages With Attachments and the part of the WSDL 1.1 specification that covers MIME bindings. MIME stands for Multipurpose Internet Mail Extensions. It's a standard that extends the format of Internet mail to allow for things like multipart message bodies. The SOAP Messages With Attachments specification takes a MIME approach in describing how to build a SOAP message.

Through this added support, a client can use JAX-RPC to access services through XML (SOAP-based) RPC calls (just as a client could previously), but include attachments in the call (JAX-RPC maps the attachments as method parameters). The primary difference is that the <binding> element of the WSDL description needs to specify one or more MIME parts that correspond to the MIME parts of the SOAP message with attachments. For example, here is an example of a <binding> element for an operation that adds a photo (provided as an attachment) to a photo catalog:

 

<wsdl:binding name="PhotoCatalogBinding" type="tns:PhotoCatalog">
 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
       <wsdl:operation name="addPhoto">
         <wsdl:input>
           <mime>MultipartRelated>
             <mime:part>
               <soap:body use="literal"/>
             </mime:part>
             <mime:part>
               <mime:content part="photo" type="image/jpeg"/>
             </mime:part>
          </mime:multipartRelated>
        </wsdl:operation>
  </wsdl:binding>


SOAP with Attachments API for Java (SAAJ) v1.2.1_01

SAAJ 1.2.1_01 implements SAAJ 1.2. It does not provide any additional features beyond those in SAAJ 1.2 implementation in the J2EE 1.4 SDK, but does include a number of bug fixes.

Java API for XML Registries (JAXR) v1.0.7

JAXR 1.0.7 is an updated reference implementation of JAXR 1.0. The implementation allows you to set a number of properties on a JAXR connection. For example, you can specify a property that gives a hint to the JAXR provider about the authentication method to use. Or you can specify a property that sets the maximum number of rows to be returned by a UDDI provider. Most of these properties are specified by the client. For example, here is how a client would specify the authentication method hint to the JAXR provider:

 

Properties props = new Properties();
props.setProperty("javax.xml.registry.security.authenticationMethod",
    "UDDI_GET_AUTHTOKEN");
ConnectionFactory factory = ConnectionFactory.newInstance();
factory.setProperties(props);
connection = factory.createConnection();


Sun Java Streaming XML Parser (SJSXP) v1.0

Sun Java Streaming XML Parser Version (SJSXP) 1.0, is a high performance implementation of the Streaming API for XML (StAX). Java WSDP 1.5 includes an Early Access release of SJSXP. StAX is a "pull" API for XML. By comparison, SAX and DOM are "push" APIs. In other words, the SAX and DOM APIs read-in the XML data they encounter and provide it to the application. In the case of SAX, the API provides the data, piece-by-piece, to callback methods. In the case of DOM, the API reads in the entire document and makes it available as an in-memory tree for subsequent processing by the application. A "pull" API such as StAX, simply points to a specific item of data in an XML document. The application then processes the item, as appropriate. In implementing StAX, SJSXP provides an object, called a cursor, that moves sequentially through an XML document. Using methods provided by the cursor, an application can move the cursor, item-by-item, through the document, and determine what type of XML construct the item represents. The application can then process the item appropriately.

 

For example, here is a snippet of code adapted from one of the sample programs provided with SJSXP 1.0. The sample program uses SJSXP to parse an XML file:

 

xmlif = XMLInputFactory.newInstance();
  xmlif.setProperty
    (XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,Boolean.TRUE);

FileInputStream fis = new FileInputStream(filename);
  XMLStreamReader xmlr =
    xmlif.createXMLStreamReader(filename, fis);

  while(xmlr.hasNext()){
    eventType = xmlr.next();
    switch (eventType){
          case XMLEvent.START_ELEMENT:
        System.out.println("START_ELEMENT");
      ...
  }
}


First an XMLInputFactory class is created for the input stream. The setProperty method of the XMLInputFactory class specifies properties for the parser. In the example, the property tells the parser to replace entity references it encounters. Various other parser properties can be set. The cursor's hasNext() method determines if there's an item in the file (that is, beyond where the cursor is currently pointing). If there is another item, the next() method moves the cursor to it. The next() method returns an integer constant that indicates the type of XML construct that the cursor is pointing to. For example, the START_ELEMENT constant indicates the start of an XML element. The action taken in the example is to print the returned constant.

You have the option of filtering an XML document so that the parser doesn't have to parse the entire document. You can also use SJSXP to write an XML document.

[ <<BACK] [ TOP] [ NEXT>>]