You are on page 1of 38

Web Services in Action

Web services are an important component in the J2EE platform, as they provide for
loosely-coupled communication between enterprise systems. They are ideal for
Enterprise Application Integration (EAI), particularly those systems that have evolved
over time.

Design and Architecture


The two principal Web service models -- a document-oriented model and a Remote
Procedure Call-oriented model -- from which the synchronous and asynchronous Web
service architectures are derived

Some of the issues to be considered for designing a Web service interface, including
granularity of services, the Java API for XML-based Remote Procedure Call (JAX-RPC),
and object-centric and document-centric parameter binding. Guidelines on how to
architect a Web service is based on receiving and responding to requests, delegating to
business logic, and exposing a Web service.

When to use?
Before you even begin to design a Web service, you should decide whether you need a
Web service solution for your application. Web services should be used when you need
interoperability across heterogeneous platforms. That is, when you need to expose all or
part of your application to other applications on different platforms.

Implementing a Web service makes sense when your application's clients are potentially
non-J2EE applications. Even if your application's clients are all J2EE applications, you
may still want to use Web services if your clients are scattered across the Web. However,
when clients are all J2EE applications, it may be best to use J2EE technologies and avoid
the extra performance cost of a Web service. Keep in mind that one of the key advantages
to using Web services technologies is the ability to go through firewalls.

Generic Web services


Generic Web services follow the service-oriented architecture model shown in Figure
1.1. In this model, a Web service first publishes its interface to a registry. The client then
looks up, or discovers, the Web service from the registry. Last, the client binds to the Web
service in order to use its services. In a Java programming environment, the Web service
uses the Java API for XML Registries (JAXR) to publish itself to the registry. The client
uses the same JAXR API to look up the service in the registry. The client uses JAX-RPC
to bind to and use the Web service. See Figure 1.1.
Figure 1.1 Publish-Discover-Bind Model

While this architecture showcases generic Web services, when the service provider and
the client are known to each other, they can bypass publish and discover steps of the
process. Instead, they can directly bind with each other and directly use each other's
services. This document looks at scenarios in which the service provider and the client
know each other. So no JAXR needed.

Key to Web service design is how a Web service processes requests at the server side (its
processing model) and how clients invoke and use the service (the Web service's
interaction model). Figure 1.2 shows the categorization of Web services according to
their interaction and processing models. Notice that typical Web services mix the
different interactions and processing models, along with synchronous and
asynchronous communication.

Figure 1.2 Web Service Models


A service's processing model may be business object (or method) centric or it may be
document centric. The business object-centric approach is driven by a series of
method calls. These method calls apply the business logic of the service to a set of
business objects containing the information required for processing the request. An
example of an object-centric service might be a credit card authorization Web service.
Such a service may receive the credit card details as parameters with the method calls.
The methods invoked on the service map directly to specific business logic. The
method parameters are used to map to a particular business object (such as a
session or entity object) or they are used to pass data to the business logic.

With a document-centric Web service, the business logic is kept separate from the
document content. The service receives an XML document, and that document contains
only data and no explicit binding to the business logic that is to be applied. There is no
mapping of the request to the business logic; that is, specific methods are not invoked on
the service. Instead, the Web service applies its business logic to the XML document, and
the document content determines the processing workflow. A travel agency Web service
is a good example of a document-centric service. The service receives a request: an XML
document that contains the details of the desired travel itinerary -- dates, places to visit,
preferred accommodations, and so forth. The travel agency service processes the request
according to the document content.

The interaction model encompasses the client's interaction with the Web service. A
client's interaction with a Web service can be synchronous or asynchronous, or a
combination of both types of communication. (That is, some method invocations may be
synchronous and others may be asynchronous.) When a synchronous model is followed,
the application typically uses an RPC-oriented interaction. With this type of interaction,
the client's request is mapped to a method call on the Web service's business logic on the
server. Using the credit card service as an example, the client utilizes an RPC call to
invoke a method on the credit card service's server. The client passes the method the
credit card details as an argument. The client might invoke a method to authorize use of
the credit card and pass the method an object containing the card details, such as by
invoking the method authorizeCreditCard(CreditCard cardDetails).

Document-centric processing is usually associated with an asynchronous messaging


communication. The client's request is sent as a message. The Web service receives the
message and processes it, sending the results when it completes its processing. In the case
of the travel agency service, the details of the client's travel request are sent to the service
as an XML document via a message (or as an attachment to an RPC call). The service
receives the document and parses it to determine how to process the request.

The RPC-oriented and document-oriented Web services form two ends of a


spectrum. At one end, a Web service may use a totally RPC-oriented interaction model
and object-centric processing, in which case you model it as a RPC-oriented Web service.
At the other end, a service may be completely document oriented and communicate with
asynchronous messaging.
However, keep in mind that most Web services fall somewhere between these two
cases and you can mix and match the models. Keep in mind, also, that even a purely
RPC-oriented Web service uses XML protocol (Simple Object Access Protocol),
though it keeps the use of XML transparent to the client and server. The client and
server deal with method calls and objects as parameters to these calls. The underlying
platform handles the XML.

1.2 Web Service Interaction Architectures

There are two principal architectures for Web service interfaces: synchronous Web
services and asynchronous Web services. These two architectures are distinguished by
their request-response handling. With synchronous services, clients invoke a request on a
service and then suspend their processing while they wait for a response. With
asynchronous services, clients initiate a request to a service and then resume their
processing without waiting for a response.

A Web service may combine synchronous and asynchronous architectures. Often,


this architectural decision is made based on the types of work the service performs and
the available technologies.

Synchronous Web Services

A credit card service, such as one that might be used in an e-commerce application, is a
good example of a synchronous service. The client cannot continue it’s processing until
the transaction completes, and obtaining credit approval is a prerequisite to completing
the transaction. A stock quote Web service is another example of a synchronous service.

Figure 1.3 Synchronous Web Service Interaction


Synchronous Web services are architected using a JAX-RPC servlet endpoint. The servlet
endpoint receives the client's request and then delegates the request to the service's
appropriate business logic, which may reside in the service's Web tier or Enterprise
JavaBeans (EJB ) tier.
TM TM

Figure 1.4 Synchronous Services with JAX-RPC

Asynchronous Web Services

With asynchronous services, the client invokes the service but does not -- or cannot --
wait for the response. Often, with these services, the client does not want to wait for the
response because it may take a significant amount of time for the service to process the
request. The client can continue with some other processing rather than wait for the
response. Later, when it does receive the response, it resumes whatever processing
initiated the service request.

Generally, a document-oriented approach is used for asynchronous class of services.

Figure 1.5 Asynchronous Web Service Communication


Developers can begin the design of a Web service interface with either a Java service
definition or Web Services Description Language (WSDL) definition. It is usually more
convenient to start the design of the Web service interface with a Java service definition
instead of a WSDL interface.

Generally, the model you choose for your Web service should be driven by the processing
requirements. If you decide to use an object-oriented approach, then it is recommended to
use JAX-RPC to invoke methods and pass arguments and return values with a Java
objects-to-XML binding to ensure maximum interoperability.

At the other end of the spectrum, such as for business-to-business interaction


requirements, you may model a service that follows a document-centric interaction and
processing model as a document-oriented Web service. In this model, pass documents in
JAX-RPC as javax.xml.transform.Source objects.

Object-Centric Parameter Binding

Figure 1.7 shows how a service endpoint might pass SOAP requests as a parameter to
business logic. (The approaches shown within the dotted lines are not recommended.)

Figure 1.7 Binding Parameters and Return Values in Object-Centric Processing

Document-Centric Parameter Binding

Figure 1.8 shows how requests can be passed as parameters or attachments and handled
with document-centric processing. Here, the XML document is wrapped into a Source
object (javax.xml.transform.Source) and passed to the next level. It is also possible
to pass an URL to the XML source document. In addition to the Source object argument,
other JAX-RPC arguments may be used to pass metadata, processing requirements,
security information, and so forth.
Figure 1.8 Parameter and Return Value Binding with Document-Centric Processing

Implementing a Web Service

Once you know how to model your Web service and the design approach you want to
take, then you are ready to implement the service. The key steps for implementing a Web
service are:

• Receiving a document and generating a response


• Mapping calls to internal representations
• Performing business logic
• Exposing the Web service

Performing Business Logic

The EJB tier or business layer is where the business logic is applied to a Web service
request. A Web service exists to expose an application's functionality. It typically does not
influence the business logic processing. This is particularly true for Web services using an
object-centric approach. However, there are some guidelines for performing business
logic for Web services with document-centric processing.

It is a good practice to keep an enterprise bean's document manipulation logic separate


from the business logic.

With document-centric processing, business logic is applied to data accessed through


XML documents. Thus, an enterprise bean must read and modify an XML document to
apply the business processing. Abstracting document manipulation logic from
business logic allows the bean's developer to switch between different XML
document manipulation approaches, such as DOM, SAX, JDOM, and so forth,
without affecting the business logic. In addition, it completely hides document
processing implementation details from the business logic. This is similar to the Data
Access Object (DAO) pattern, which abstracts database access code from the bean's
business logic.
In the document-centric processing model, an enterprise bean receives an XML document
that contains all information for processing a request. Typically, the XML document has
well-defined segments containing details about a specific entity.

Rather than pass the entire document to different components, it's best if the receiving
bean breaks the document into fragments and passes only the required fragments to other
components that implement portions of the business logic.

Designing for Performance

Good design and proper use of the technologies can greatly improve Web service
performance. You should consider the following performance recommendations when
designing a Web service.

1.4.5.1 Using Caching and Service Granularity

Web service clients tend to be richer clients and thus can do more work on the client side,
such as caching. Web services can maximize performance by correctly using data
caching. You should consider using caching in a Web service when the service's requested
information is primarily read only or when that information changes at a slower rate than
at which it is requested.

Caching at the client side may also be effective when the service's granularity of
operation is more coarse grained than that of the client requestor. (See Granularity of Web
Services.) In such a situation, the service provides more information than the client needs
for a particular request. However, if the client issues similar requests, then caching the
data may improve response time. This is especially true for clients making synchronous
requests, since they must consider the time to construct the response in addition to the
time to transfer the data.

On the other hand, fine-grained Web services transfer smaller sets of data but may handle
more requests within the same time frame. The amount of time to handle the SOAP
protocol, including parsing the XML document request and constructing the XML
response, becomes critical, and caching may be useful on the server side. This is
especially true when the service exposes fine-grained operations to distributed
applications but internally handles coarse-grained requests. Consider caching on the
server the SOAP request and response to the Web service itself (with SOAP message
handlers) and any internal requests and responses between the Web tier and the EJB tier.

1.4.5.2 Using XML

XML, while it has many benefits, also has performance disadvantages. XML often
demands a great deal of CPU processing. Most XML documents must not only be parsed
but also validated, and many require additional processing. Processing XML documents
also requires a large amount of memory. Typically, XML processing may require creating
large numbers of objects, especially when handling document object models of any kind.
XML may also be network intensive. A given document may be the aggregation of
different external entities. Parsing the document may require that each entity be retrieved
across the network.

The following guidelines help minimize the performance overhead of using XML.

• Use XML judiciously. Use XML when you must interoperate with heterogeneous
systems and provide loosely-coupled integration points. Try to rely on XML
protocols such as those implemented by JAX-RPC. Maximize interoperability by
using existing public vertical schemas. Avoid using XML for unexposed
interfaces or for exchanges between components that are tightly coupled.
• Avoid unnecessary parsing and validation. Because processing XML
documents may be CPU, network, and memory expensive, it's best to keep to a
minimum such operations. You should parse incoming XML documents only
when the request is properly formulated, such as documents passed as Source
parameters to JAX-RPC calls. Validate the document's meta information, which
may have been passed as additional JAX-RPC arguments, and perform the
security validation before retrieving the document. Always try to use the proper
API to process the document.
• Bind documents to domain Java objects as soon as possible. Then process the
Java objects rather than the XML documents.

Additional guidelines apply when implementing an application that spans multiple


containers. When the application components interact remotely, try to pass only Java
objects. Also consider using the Transfer Object design pattern. With remote interaction,
it is expensive to pass DOM trees, plus not all implementations support Java serialization
of DOM trees. While using serialized XML is expensive and thus best avoided, it may be
required to provide loosely-coupled integration points.
Creating Web Services

Developing a Web service using JAX-RPC is surprisingly easy. The service itself is
basically two files, an interface that declares the service’s remote procedures and a
class that implements those procedures.

Runtime is when a program is running (or being executable). That is, when you start a
program running in a computer, it is runtime for that program. In some programming
languages, certain reusable programs or "routines" are built and packaged as a "runtime
library." These routines can be linked to and used by any program when it is running.

public class Runtime


extends Object

Every Java application has a single instance of class Runtime that allows the
application to interface with the environment in which the application is running. The
current runtime can be obtained from the getRuntime method.

Web services overview

The Web services wizard generates files for the Requestor and the Provider. The Web
services wizard supports a number of servers and run-times. Figure shows a list of run-
times being shipped with Rational Application Developer.

Rational Application Developer run-times and servers

Artifacts that the Web services wizard generates

The wizard generates three sets of artifacts: 1) The Web service Requestor-side artifacts
including the Proxy Bean, 2) the WSDL file, and 3) the Web service Provider-side files. A
Web service can be based on a number of different types including a Java bean,
Enterprise Java Bean (EJB) component, DADX document, and so on.
Starting from a WSDL file (Top Down or Client scenario) or from a Java file (Bottom
Up scenario).

Bottom Up Web services scenario

You can start at different points in the wizard and create a Web service using different file
types. One start point is with a Java Bean. The Web services wizard would then generate
the Requestor-side files including the proxy bean, the WSDL file, and Provider-side files.
This is known as the Bottom Up

Top Down scenario

You can also start with a WSDL file and generate the Requestor-side artifacts and the
Provider artifacts including a skeleton bean with the WSDL operations. The
implementation is left to you to fill in. This is known as the Skeleton or Top Down
Scenario.
The following interface definition is a simple example showing the methods a wholesale
coffee distributor might want to make available to its prospective customers. Note that a
service definition interface extends java.rmi.Remote and its methods throw a
java.rmi.RemoteException object.

package coffees;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface CoffeeOrderIF extends Remote {
public Coffee [] getPriceList()
throws RemoteException;
public String orderCoffee(String coffeeName, int quantity)
throws RemoteException;
}

The method getPriceList returns an array of Coffee objects, each of which contains a
name field and a price field. There is one Coffee object for each of the coffees the
distributor currently has for sale. The method orderCoffee returns a String that might
confirm the order or state that it is on back order.

The following example shows what the implementation might look like (with
implementation details omitted). Presumably, the method getPriceList will query the
company's database to get the current information and return the result as an array of
Coffee objects. The second method, orderCoffee, will also need to query the database
to see if the particular coffee specified is available in the quantity ordered. If so, the
implementation will set the internal order process in motion and send a reply informing
the customer that the order will be filled. If the quantity ordered is not available, the
implementation might place its own order to replenish its supply and notify the customer
that the coffee is backordered.

package coffees;
public class CoffeeOrderImpl implements CoffeeOrderIF {
public Coffee [] getPriceList() throws RemoteException; {
. . .
}
public String orderCoffee(String coffeeName, int quantity)
throws RemoteException; {
. . .
}
}
Web Services Clients

We will now turn our attention from providing web services to consuming them. Writing
the client application for a Web service entails simply writing code that invokes the
desired method. Of course, much more is required to build the remote method call and
transmit it to the Web service, but that is all done behind the scenes and is invisible to
the client.

The method getPriceList will block until it has received a response and returned it.
Because a WSDL document is being used, the JAX-RPC runtime will get the service
endpoint from it. Thus, in this case, the client class does not need to specify the
destination for the remote procedure call. When the service endpoint does need to be
given, it can be supplied as an argument on the command line. Here is what a client class
might look like:

package coffees;
public class CoffeeClient {
public static void main(String[] args) {
try {
CoffeeOrderIF coffeeOrder = new
CoffeeOrderServiceImpl().getCoffeeOrderIF();
Coffee [] priceList =
coffeeOrder.getPriceList():
for (int i = 0; i < priceList.length; i++) {
System.out.print(priceList[i].getName() + " ");
System.out.println(priceList[i].getPrice());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Invoking a Remote Method

Once a client has discovered a Web service, it can invoke one of the service's methods.
The following example makes the remote method call getPriceList, which takes no
arguments. As noted previously, the JAX-RPC runtime can determine the endpoint for the
CoffeeOrder service (which is its URI) from its WSDL description. If a WSDL document
had not been used, you would need to supply the service's URI as a command line
argument. After you have compiled the file CoffeeClient.java, here is all you need to
type at the command line to invoke its getPriceList method.

java coffees.CoffeeClient

The remote procedure call made by the previous line of code is a static method call. In
other words, the RPC was determined at compile time. It should be noted that with JAX-
RPC, it is also possible to call a remote method dynamically at run time. This can be done
using either the Dynamic Invocation Interface (DII) or a dynamic proxy.
• HelloIF.java - the service definition interface
• HelloImpl.java - the implementation class for the HelloIF interface
• config.xml - a configuration file read by the xrpcc tool, which creates the stub
and tie classes
• web.xml - a deployment descriptor for the Web component (a servlet) that
dispatches to the service
• HelloClient.java - the remote client that contacts the service and then invokes
the sayHello method

http://www.ibm.com/developerworks/webservices/library/ws-javaclient/index.html

Web services standards for Java


The development of Java technology standards occurs through Java Specification
Requests (JSRs) being submitted to the Java Community Process (JCP). Two JSRs
cover the Java Web services architecture:

1. JSR 101: Java API for XML based RPC (JAX-RPC)


2. JSR 109: Implementing Enterprise Web services.

Both specifications provide conformance and interoperability requirements for


vendors' implementations.

JAX-RPC

JAX-RPC defines a simple and easy-to-use Java Application Programming Interface


(API) for XML-based Remote Procedure Calls (RPC) and the Java to XML and XML to
Java mapping:

• WSDL to Java and Java to WSDL mappings: For example, a WSDL port type is
mapped to a Java Service Endpoint Interface (SEI).
• XML data type to Java data type and Java data type to XML data type mappings,
including simple types, complex types, and arrays.

In addition to XML mappings, JAX-RPC also defines the client-side programming model
and API, which I will cover in more details in later sections. JAX-RPC 1.1 adds
interoperability requirements based on the Web Services Interoperability organization
(WS-I) Basic Profile version 1.0.

JSR 109

JSR 109 specifies the Web services programming model and architecture for the Java 2
Enterprise Edition (J2EE) environment. JSR 109 builds on SOAP 1.1 and WSDL 1.1 to
cover the use of JAX-RPC in a J2EE environment (Figure 2). It also defines a
deployment model to J2EE application servers. JSR 109's client-side programming
model, which I will cover in sections below, is conformant to JAX-RPC.
Figure 2. JSR 109 and JAX-RPC

JAX-RPC 1.1 and JSR 109 are part of J2EE 1.4.

Service lookup

There are two families of clients, which differ in the way the code is written, packaged,
and invoked:

1. Unmanaged clients
2. J2EE container-managed clients.

Here, unmanaged means not J2EE container-managed. These are Java 2 Standard Edition
(J2SE) clients and are invoked with a simple java command. For unmanaged clients, the
service lookup is through the JAX-RPC ServiceFactory, a factory for the creation of
instances of services access points. For J2EE
container-managed clients, service lookup is through ServiceFactory
JNDI lookup.
JSR 101: "The JAX-RPC
ServiceFactory is the standard
JAX-RPC ServiceFactory way to look up Web services in a
J2SE environment."
The JAX-RPC ServiceFactory is an abstract class
which acts as a factory for instantiating JAX-RPC Services. It is vendor independent
and lets you write portable code.

javax.xml.rpc.Service service =
ServiceFactory.newInstance().createService(...);

You need to pass the fully qualified name of the Web service, that is namespace plus
service name, to the createService() method and optionally the URL of the WSDL
document describing the Web service you want to look up. The steps are as follows:
1. Optionally, specify the WSDL URL.
2. Specify the Web service's fully qualified name.
3. Invoke ServiceFactory's createService() method.

The Service Interface obtained is then used to get a stub, dynamic proxy, or DII Call
object, as described in the "Service access" section. Also covered in that section is the
Dynamic Invocation Interface (DII). With this method, you do not need to know the
WSDL URL of the Web service you want to invoke, and you only specify the service
name parameter to the createService() method. Listing 1 shows how to use the
ServiceFactory to instantiate a JAX-RPC Service. QName is a
javax.xml.namespace.QName.

Listing 1. Using the JAX-RPC ServiceFactory to obtain a JAX-RPC Service


String wsdlURL =
http://localhost:6080/HelloWebService/services/Hello?wsdl";
String namespace = "http://Hello.com";
String serviceName = "HelloWebService";
QName serviceQN = new QName(namespace, serviceName);

ServiceFactory serviceFactory = ServiceFactory.newInstance();


/* The "new URL(wsdlURL)" parameter is optional */
Service service = serviceFactory.createService(new URL(wsdlURL),
serviceQN);

JNDI lookup

JNDI service lookup JSR 109: "JNDI lookup is the


standard way to look up Web
J2EE container-managed clients are packaged into services in a J2EE environment."
Enterprise Archives (.EAR) files and run from inside
a J2EE container. In addition to the Java code, descriptors are also packaged into the
archive. Several different types of J2EE container-managed clients are:

• Application client container clients


• Web container clients: JavaBean or Servlet
• EJB container clients: EJB

JAX-RPC defines the programming model for unmanaged clients, whereas JSR 109,
"Implementing Enterprise Web services", defines the programming model for J2EE
container-managed clients. One of the goals of JSR 109 is that its client programming
model is compatible with JAX-RPC. However, JSR 109 does not recommend the use of
the JAX-RPC ServiceFactory. It recommends clients use Java Naming and Directory
Interface (JNDI) instead to obtain a Service Interface. This is a two step process, also
illustrated in Listing 2:

1. Instantiate a local JNDI Context.


2. Do a JNDI lookup for the Web service name in this context.

Listing 2. JNDI service lookup


Context ic = new InitialContext();
Service service = (Service) ctx.lookup("java:comp/env/service/HelloService");

The name of the Web service, in this case java:comp/env/service/HelloService, is


specified in the client application's deployment descriptor. JSR 109 recommends that all
service reference logical names be organized under the service sub-context. With the
client environment context being java:comp/env, you end up with:

service name in context =


client environment context + "service" subcontext + service name.

In this case, the service name in context is:

java:comp/env/ + service/ + HelloService.

service subcontext + service name (for example, service/HelloService) is also


called the logical service name and is declared in the Web service client application's
deployment descriptor.

The JNDI lookup returns a JAX-RPC Service Interface. The J2EE container makes sure
an implementation of the generic JAX-RPC Service is bound at the location specified in
the deployment descriptor. You can also cast the object returned by the lookup to the
specific interface for your Web service. This is shown on Listing 3, where the
HelloService extends the generic JAX-RPC Service interface.

Listing 3. Alternative JNDI lookup


Context ic= new InitialContext();
HelloServiceInterface service =
(HelloServiceInterface)
ic.lookup("java:comp/env/service/HelloService");

The Service Interface obtained is then used to get a static stub, dynamic proxy, or a DII
Call object, as described in the "Service access" section below.

Service access

In previous sections, you saw that a JAX-RPC ServiceFactory acts as a factory for
JAX-RPC Services. Similarly, a JAX-RPC Service acts as a factory for proxies and stubs.
Once you have instantiated a Service, there are three methods for accessing and invoking
the Web service:

1. Stub
2. Dynamic Proxy
3. Dynamic Invocation Interface (DII).

Stub and dynamic proxy methods use the Service Endpoint Interface (SEI). It is basically
the Java representation of the Web service operations described in the WSDL port type
element. It is a Java interface defining methods used by the Java client to interact with the
Web service. The SEI is generated by a WSDL to Java mapping tool (such as Apache
Axis' Java2WSDL or IBM WSDK's WSDL2Client).

SEI

Stub A Service Endpoint Interface


(SEI) is the Java representation
The stub method uses a platform-specific stub of a WSDL port type.
created before runtime during the WSDL to Java
mapping stage. Because the stub is created before runtime, it is sometimes called a static
stub. It is a Java class implementing the SEI. A WSDL to Java mapping tool generates the
client-side artifacts needed; basically, the tool imports the WSDL service definition and
creates the corresponding Java code. The artifacts include an SEI, a Stub, and optionally
holders, serializers, deserializers, and utility classes. JAX-RPC recommends an instance
of a stub to be bound to a specific protocol and transport, such as a SOAP binding stub.
For the stub method, the steps to perform are:

1. Get a JAX-RPC Service.


2. Obtain a stub.
3. Invoke the Web service's operations on the stub.

Steps 2 and 3 are shown in Listing 4. Note that it is also possible to use the JAX-RPC
Service's getPort method (described in the next section) to obtain a stub.

Listing 4. Accessing a Web service through a stub


Hello myStub = (Hello) service.getHello();
System.out.println(myStub.getGreeting("Jane");

The advantage of this method is its simplicity. Basically, only two lines of code are
required to access and invoke a Web service's operation. However, you need to know the
WSDL URL at development-time and run your WSDL to Java mapping tool. Also, these
stubs are not portable because they depend on implementation classes and should not be
packaged as part of an application. The design of portable stubs is out-of-scope for JAX-
RPC 1.0 and 1.1.

Dynamic proxy

From a JAX-RPC Service, you can use a proxy to invoke the Web service's operations.
The proxy is a Java class implementing the SEI. A proxy is obtained with the JAX-RPC
Service's getPort() method, which takes the name of the port for the Web service you
want to invoke (found in the WSDL document), as well as the SEI implemented by the
proxy. It is called dynamic because the proxy is created at runtime. The steps for dynamic
proxy clients are:

1. Get a JAX-RPC Service.


2. Obtain a proxy using the JAX-RPC Service's getPort() method in order to invoke
the Web service's operations.

In step 1, for unmanaged clients, a JAX-RPC Service is obtained from the JAX-RPC
ServiceFactory by passing the WSDL URL as well as the Web service name parameter
to the createService() method. For J2EE container-managed clients, you get a JAX-RPC
Service from JNDI lookup. Listing 5 shows the dynamic proxy method (step 2) to
invoke the "getGreeting" operation on the Web service.

Listing 5. Invoking a Web Service's operation on a dynamic proxy


String namespace = "http://Hello.com";
String portName = "Hello";
QName portQN = new QName(namespace, portName);

Hello myProxy = service.getPort(portQN, Hello.class);


System.out.println(myProxy.getGreeting("Jane"));

This is all the code you need to write to invoke a Web service using the dynamic proxy
method. The advantage of using this method is that you write portable, vendor-
independent code. However, you need to know the WSDL URL at development-time and
you need to run your WSDL to Java mapping tool against the WSDL document before
runtime. If you do not have this information, or if the WSDL URL is likely to change,
you should use the DII method instead.

Dynamic Invocation Interface (DII)

The JAX-RPC Call interface supports the dynamic invocation of a Web services'
operations. With this method, you do not need to know the WSDL URL at development-
time. Instead of obtaining a proxy from the JAX-RPC Service, the JAX-RPC Service
acts as a factory for instantiating JAX-RPC Calls. The steps for this method are:

1. Get a JAX-RPC Service.


2. Instantiate a JAX-RPC Call using JAX-RPC Service's createCall() method.
3. Configure your Call instance with its setter methods.
4. Invoke the Web service's operation using the JAX-RPC Call's invoke method.

In step 1, for unmanaged clients, a JAX-RPC Service is obtained from the JAX-RPC
ServiceFactory by passing only the name of the Web service (not the WSDL URL) to
the createService() method. For J2EE container-managed clients, you get a JAX-RPC
Service from JNDI lookup. In step 3, configuration parameters are: name of the
operation, port type, address of the target service endpoint, return type. Refer to section
8.2.4.2 of the JAX-RPC specification for the standard set of properties (see Resources).
Steps 2 to 4 are shown in Listing 6.

Listing 6. Invoking a Web service using the DII method


String namespace = "http://Hello.com";
String portName = "Hello";
QName portQN = new QName(namespace, portName);
String operationName = "getGreeting";

Call call = service.createCall();


call.setPortTypeName(portQN);
call.setOperationName(new QName(namespace, operationName));
call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY, "");
call.addParameter("param1", <xsd:string>,ParameterMode.IN);
call.setReturnType(<xsd:string>);
Object[] inParams = new Object[] {"Jane"};
String ret = (String) call.invoke(inParams);

You can reuse the Call instance to invoke other operations on the Web service.

Note: What was just described is not the only way to invoke them. For example, it is
possible to invoke createCall() with port type name and operation name parameters.

Making DII calls through a Call object is programmatically more complex than using a
stub or dynamic proxy. However, the advantage of using a DII Call interface is that a
client can call a remote procedure without development-time knowledge of the WSDL
URI or the Web service operations' signatures. This makes the code easy to modify if the
Web service details change. With DII clients, runtime classes generated by WSDL to Java
mapping tools (emitters) are not required like the dynamic proxy or static stub cases.
However, if you know the Web service you want to invoke is unlikely to change, you
should use dynamic proxy because configuring the Call instance can be complex.
Dynamic Discovery and Invocation (DDI)

Dynamic Discovery and Invocation (DDI) is the ultimate use of Web services' flexibility
where a Web service client can dynamically discover and invoke a Web service without
any prior knowledge of it. Although DII clients, described in the previous section, do not
require development-time knowledge of a Web service's details, they do not involve the
process of discovering the Web service. A DDI client performs three steps:

1. Discovers the Web service's details from UDDI: finds the business providing the
service and then the URL of the WSDL document describing the service
2. Reads the WSDL document to find information on the Web service: namespace,
service, ports, and parameters
3. Invokes the service.

In step 1, the UDDI Registry Enquiry API is used to browse the UDDI registry. In step 2,
the UDDI4J API is used to parse the WSDL document. Finally, in step 3, the DII method
(described in the previous section) is used.
Exposing Model Data via Web Services

• Servlet Endpoint
• EJB Endpoint

Create and expose a Session Facade for the application. Using a Session Facade to
expose an application's operations will make it easier to migrate to enterprise bean
endpoints at a later date.

Create reusable enterprise bean components that expose an XML interface in the form of
a generic XML schema. This allows the enterprise bean component to be reused in the
context of a Web service. For document-centric Web services, a document can flow to the
EJB tier and enterprise bean components can manipulate the document. Object-centric
Web services deserialize documents at the service endpoint.

The biggest new feature of J2EE 1.4 is the ability of J2EE components to act both as web
service providers and consumers. “J2EE applications can expose a web service from
the EJB tier using a stateless session bean or from the web tier using a plain Java
object.” Additionally, both server-side components and J2EE client applications have a
standard way of declaring references to external web services.

http://docs.jboss.org/jbossas/jboss4guide/r2/html/ch12.html
SOAP Handlers

JAX-RPC requires SOAP over HTTP for interoperability. JAX-RPC provides support for
SOAP message processing model through the SOAP message handler functionality. This
enables developers to build SOAP specific extensions to support security, logging and
any other facility based on the SOAP messaging. JAX-RPC uses SAAJ API for SOAP
message handlers. SAAJ provides a standard Java API for constructing and
manipulating SOAP messages with attachments.

JAX-RPC provides support for document-based messaging. Using JAX-RPC, any


MIME-encoded content can be carried as part of a SOAP message with attachments. This
enables exchange of XML documents, images and other MIME types across Web
services.

JAX-RPC supports HTTP level session management and SSL based security
mechanisms. This enables you to develop secure Web services. More advanced SOAP
message-level security will be addressed in the evolution of JAX-RPC technology.

Steps for Implementing a Service:

1. Define Web Service Endpoint Interface


2. Implement Web Service class and methods
3. Package and deploy

JAX-RPC handlers allow you to intercept a SOAP message at various times during
a service invocation. Handlers are similar to servlet filters. Handlers can exist on both
the client and the server side. If you use JAX-RPC on the client side, you can have a
handler process a SOAP request message right before it goes on the network, and you can
process the response message before it is returned to the client. Similarly, you can
intercept an incoming SOAP request message on the server before invoking the service
implementation, as well as the outgoing response.

Several handlers can be combined into what is called a "handler chain". Each handler
processes the SOAP message, which is then passed on to the next handler in the chain.
The exact sequence in which this happens is configurable.

To develop a JAX-RPC handler, you simply create a class that implements the
javax.xml.rpc.handler.Handler interface. It has three methods to handle SOAP
requests, responses and faults, respectively.

Handlers are defined in the JAX-RPC specification. However, the "Enterprise Web
Services" (JSR109) specification describes how they are used in a J2EE environment and
adds some clarification to the way handlers are managed by the application server. We
will assume that your Web service runs on a J2EE application server and hence we will
follow the definitions of JSR109 as well as JAX-RPC.
Handlers are shared across multiple service invocations. In other words, they can store
information that is only valid for a particular client or server instance. You can compare
this to the way servlets are handled. When a new instance of a handler is created, its
init(...) method is called. That allows you to set up things that you can use for
multiple invocations. Before the handler is removed, the destroy() method is called, so
that you can do cleanup in there. As a rule of thumb, however, you should avoid storing
any state in a handler altogether.

Handlers can be configured either programmatically or, in case you are running a J2EE
application server, they are configured in the Web service deployment descriptor.
Handlers and handler chains are defined on a per service basis. They can be defined in
both the server and client side deployment descriptors. Listing below shows the
deployment descriptor for our sample service, showing how a handler class called
handler.PerformanceHandler is registered for the HelloWorldService service
(webservices.xml):

Now let's look at how you can create a handler that measures the response time of your
service implementation. We will assume that you have created a HelloWorld web
service, which simply returns a String message. Listing below shows the code for the
service implementation bean:

public class HelloWorld {


public String helloWorld(String message) {
return "Hello " + message;
}
}

The handler will be configured for the server that hosts the Web service. It will be
invoked on both the request and the response message, so that we can measure the
elapsed time.

Each handler must implement the javax.xml.rpc.handler.Handler interface. Or,


you can make your life a bit easier by simply inheriting the
javax.xml.rpc.handler.GenericHandler class, which provides default
implementations for all the methods. For storing performance results, we use a class
called Logger, which we set up in the init() method. Moreover, the application server
passes a javax.xml.rpc.handler.HandlerInfo object into this method, which we need
to cache as well:
public class PerformanceHandler extends GenericHandler {

protected HandlerInfo info = null;


protected Logger logger = null;

public void init(HandlerInfo arg) {


info = arg;
logger =
Logger.getLogger("c://temp//HelloWorldServiceLog");
}

public void destroy() {


try {
logger.close();
} catch (Exception x) {}
}

...
}

Note that we close the Logger object when the handler instance is destroyed.

Each handler implements the handleRequest method, which is invoked when a


request message arrives:

public boolean handleRequest(MessageContext context) {


try {
Date startTime = new Date();
context.setProperty("startTime", startTime);
} catch (Exception x) {
x.printStackTrace();
}
return true;
}

Here you can see that we store the current time in the message context as a property
called "startTime". The application server will guarantee that the same message context
object is passed into the handleResponse method, so that we can measure the elapsed
time there:
public boolean handleResponse(MessageContext context) {
try {
Date startTime = (Date)context.getProperty("startTime");
Date endTime = new Date();
long elapsedTime = endTime.getTime() -
startTime.getTime();
logger.write("Elapsed time is " + elapsedTime+"\n");
} catch (Exception x) {
x.printStackTrace();
}
return true;
}
JAX-RPC defines a mechanism with which you can manage service invocations by
intercepting request and response messages without having to change the actual service
consumer or provider. In J2EE, you can configure handlers in a deployment descriptor,
without writing any code, providing you with a powerful way of controlling SOAP
messages as they pass through your system.

Handlers let you access/modify SOAP request and response messages, but typically used
to process service contexts in SOAP header blocks.

Possible example handlers: encryption, decryption, authentication, authorization,


logging, auditing, caching.

Handlers are pluggable and chainable through standardized programming API, portable
across implementations. Handler has its own lifecycle: JAX-RPC runtime system calls
init(...), destroy() of a handler. Handler instances can be pooled (stateless).
MessageContext is used to share properties among handlers in a handler chain.

On the service client side: a request handler is invoked before an RPC request is
communicated to the target service endpoint, a response or fault handler is invoked
before an RPC response is returned to the client.

On a service endpoint: a request handler is invoked before an RPC request is


dispatched to the target service endpoint, a response or fault handler is invoked before
communication back to the service client from the target service endpoint.

javax.xml.rpc.handler.Handler interface is required to be implemented by a SOAP


message handler:

***********************************************************************
THE BASIC HANDLER INTERFACE AND THE GENERIC HANDLER ABSTRACT CLASS
***********************************************************************
package javax.xml.rpc.handler;

import javax.xml.namespace.QName;

public interface Handler {

public boolean handleRequest(MessageContext context); // 'false'


will block the HandlerChain
public boolean handleResponse(MessageContext context); // 'false'
will block the HandlerChain
public boolean handleFault(MessageContext context); // 'false' will
block the HandlerChain
public abstract void init(HandlerInfo config);
public abstract void destroy();
public QName[] getHeaders();

}
package javax.xml.rpc.handler;

import javax.xml.namespace.QName;

public abstract class GenericHandler implements Handler {

protected GenericHandler() {}

public boolean handleRequest(MessageContext context) {


return true;
}

public boolean handleResponse(MessageContext context) {


return true;
}

public boolean handleFault(MessageContext context) {


return true;
}

public void init(HandlerInfo config) {}


public void destroy() {}
public abstract QName[] getHeaders();
}

***********************************************************************

Example of generic SOAP message handler:

package com.example;

public class SampleSOAPHeaderHandler implements


javax.xml.rpc.handler.Handler {

public SampleSOAPHeaderHandler() { ... }

public boolean handleRequest(MessageContext context) {


try {
SOAPMessageContext smc =
(SOAPMessageContext)context;
SOAPMessage msg = smc.getMessage();
SOAPPart sp = msg.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
SOAPHeader sh = se.getHeader();

// Process one or more header blocks


// ...
// Next step based on the processing model for
this handler

} catch(Exception ex) {
// throw exception
}
}
}

Alternative: Sample handler which extends GenericHandler:

package com.example;

public class SampleSOAPHeaderHandler extends GenericHandler {

public boolean handleRequest(MessageContext ctx) {


try {
SOAPMessageContext mc = (SOAPMessageContext)ctx;
SOAPMessage msg = mc.getMessage();
SOAPPart sp = msg.getSOAPPart();
SOAPEnvelop se = sp.getEnvelope();
SOAPHeader header= se.getHeader();

// now we can process the header

if (everything is fine) {
return true; // with 'true' handler chain
continues processing
} else {
return false; // return 'false' results
in chaining to stop
}
} catch(Exception ex) {}
}
}

SAAJ API

--Alternate API for XML processing

http://www.ibm.com/developerworks/xml/library/x-jaxmsoap/
XML Parsers
The Extensible Markup Language (XML) and Java technology are natural partners in
helping developers exchange data and programs across the Internet. That's because XML
has emerged as the standard for exchanging data across disparate systems, and Java
technology provides a platform for building portable applications.

This partnership is particularly important for Web services, which promise users and
application developers program functionality on demand from anywhere to anywhere on
the Web. XML and Java technology are recognized as ideal building blocks for
developing Web services and applications that access Web services.

But how do you couple these partners in practice? More specifically, how do you access
and use an XML document (that is, a file containing XML-tagged data) through the Java
programming language? One way to do this, perhaps the most typical way, is through
parsers that conform to the Simple API for XML (SAX) or the Document Object Model
(DOM). Both of these parsers are provided by Java API for XML Processing (JAXP).
Java developers can invoke a SAX or DOM parser in an application through the JAXP
API to parse an XML document -- that is, scan the document and logically break it up
into discrete pieces. The parsed content is then made available to the application.

SAX

The SAX API

The Simple API for XML (SAX) defines an API for an event-based parser. Being event-
based means that the parser reads an XML document from beginning to end, and each
time it recognizes a syntax construction, it notifies the application that is running it. The
SAX parser notifies the application by calling methods from the ContentHandler
interface. For example, when the parser comes to a less than symbol ("<"), it calls the
startElement method; when it comes to character data, it calls the characters method;
when it comes to the less than symbol followed by a slash ("</"), it calls the endElement
method, and so on. To illustrate, let's look at part of the example XML document from the
first section and walk through what the parser does for each line. (For simplicity, calls to
the method ignorableWhiteSpace are not included.)

<priceList> [parser calls startElement]


<coffee> [parser calls startElement]
<name>Mocha Java</name> [parser calls startElement,
characters, and endElement]
<price>11.95</price> [parser calls startElement,
characters, and endElement]
</coffee> [parser calls endElement]
The default implementations of the methods that the parser calls do nothing, so you need
to write a subclass implementing the appropriate methods to get the functionality you
want. For example, suppose you want to get the price per pound for Mocha Java. You
would write a class extending DefaultHandler (the default implementation of
ContentHandler) in which you write your own implementations of the methods
startElement and characters.

You first need to create a SAXParser object from a SAXParserFactory object.

SAXParserFactory factory = SAXParserFactory.newInstance();


SAXParser saxParser = factory.newSAXParser();
saxParser.parse("priceList.xml", handler);

The result of calling the method parse depends, of course, on how the methods in handler
were implemented. The SAX parser will go through the file priceList.xml line by line,
calling the appropriate methods. In addition to the methods already mentioned, the parser
will call other methods such as startDocument, endDocument, ignorableWhiteSpace, and
processingInstructions, but these methods still have their default implementations and
thus do nothing.

The following method definitions show one way to implement the methods characters
and startElement so that they find the price for Mocha Java and print it out. Because of
the way the SAX parser works, these two methods work together to look for the name
element, the characters "Mocha Java", and the price element immediately following

public void startElement(..., String elementName, ...){


if(elementName.equals("name")){
inName = true;
} else if(elementName.equals("price") && inMochaJava ){
inPrice = true;
inName = false;
}
}
public void characters(char [] buf, int offset, int len) {
String s = new String(buf, offset, len);
if (inName && s.equals("Mocha Java")) {
inMochaJava = true;
inName = false;
} else if (inPrice) {
System.out.println("The price of Mocha Java is: " + s);
inMochaJava = false;
inPrice = false;
}
}
}
Once the parser has come to the Mocha Java coffee element, here is the relevant state
after the following method calls:

next invocation of startElement -- inName is true

next invocation of characters -- inMochaJava is true

next invocation of startElement -- inPrice is true

next invocation of characters -- prints price

The SAX parser can perform validation while it is parsing XML data, which means that it
checks that the data follows the rules specified in the XML document's schema. A SAX
parser will be validating if it is created by a SAXParserFactory object that has had
validation turned on. This is done for the SAXParserFactory object factory in the
following line of code.

factory.setValidating(true);

When it comes to fast, efficient reading of XML data, SAX is hard to beat. It requires
little memory, because it does not construct an internal representation (tree structure) of
the XML data. Instead, it simply sends data to the application as it is read—your
application can then do whatever it wants to do with the data it sees.

In effect, the SAX API acts like a serial I/O stream. You see the data as it streams in, but
you can’t go back to an earlier position or leap ahead to a different position. In general, it
works well when you simply want to read data and have the application act on it.

The DOM API

The Document Object Model (DOM), defined by the W3C DOM Working Group, is a set
of interfaces for building an object representation, in the form of a tree, of a parsed XML
document. Once you build the DOM, you can manipulate it with DOM methods such as
insert and remove, just as you would manipulate any other tree data structure. Thus,
unlike a SAX parser, a DOM parser allows random access to particular pieces of data in
an XML document. Another difference is that with a SAX parser, you can only read an
XML document, but with a DOM parser, you can build an object representation of the
document and manipulate it in memory, adding a new element or deleting an existing
one.

In the previous example, we used a SAX parser to look for just one piece of data in a
document. Using a DOM parser would have required having the whole document object
model in memory, which is generally less efficient for searches involving just a few
items, especially if the document is large. In the next example, we add a new coffee to the
price list using a DOM parser. We cannot use a SAX parser for modifying the price list
because it only reads data.

Let's suppose that you want to add Kona coffee to the price list. You would read the XML
price list file into a DOM and then insert the new coffee element, with its name and price.
The following code fragment creates a DocumentBuilderFactory object, which is then
used to create the DocumentBuilder object builder. The code then calls the parse
method on builder, passing it the file priceList.xml.

DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("priceList.xml");

At this point, document is a DOM representation of the price list sitting in memory.

//We're at the Mocha Java node. Create and insert the new element.

Node newCoffeeNode = document.createElement("coffee");

Node newNameNode = document.createElement("name");


Text tnNode = document.createTextNode("Kona");
newNameNode.appendChild(tnNode);

Node newPriceNode = document.createElement("price");


Text tpNode = document.createTextNode("13.50");
newPriceNode.appendChild(tpNode);

http://java.sun.com/j2ee/1.3/docs/tutorial/doc/IntroWS4.html
JAXB
JAXB allows Java developers to access and process XML data without having to
know XML or XML processing. For example, there's no need to create or use a SAX
parser or write callback methods.

Using JAXB, you would:

• Bind the schema for the XML document.


• Unmarshal the document into Java content objects. The Java content objects represent
the content and organization of the XML document, and are directly available to your
program.

After unmarshalling, your program can access and display the data in the XML document
simply by accessing the data in the Java content objects and then displaying it. There is
no need to create and use a parser and no need to write a content handler with callback
methods. What this means is that developers can access and process XML data without
having to know XML or XML processing.

Bind the Schema


JAXB simplifies access to an XML document from a Java program by presenting the
XML document to the program in a Java format. The first step in this process is to bind
the schema for the XML document into a set of Java classes that represents the schema.

Schema: A schema is an XML specification that governs the allowable components of an


XML document and the relationships between the components. For example, a schema
identifies the elements that can appear in an XML document, in what order they must
appear, what attributes they can have, and which elements are subordinate (that is, are
child elements) to other elements. An XML document does not have to have a schema,
but if it does, it must conform to that schema to be a valid XML document. JAXB
requires that the XML document you want to access has a schema, and that schema is
written in the W3C XML Schema Language (see the box "Why W3C XML Schema
Language?").

Why W3C XML Schema Language?

The W3C XML Schema Language is not the only schema language. In fact, the XML
specification describes document-type definitions (DTDs) as the way to express a
schema. In addition, pre-release versions of the JAXB Reference Implementation
worked only with DTDs -- that is, not with schemas written in the XML Schema
Language. However, the XML Schema Language is much richer than DTDs. For
example, schemas written in the XML Schema Language can describe structural
relationships and data types that can't be expressed (or can't easily be expressed) in
DTDs. There are tools available to convert DTDs to the W3C XML Schema Language,
so if you have DTD-based schemas that you used with an earlier version of the JAXB
Reference Implementation, you can use these tools to convert the schemas to XML
Schema Language.

Binding: Binding a schema means generating a set of Java classes that represents the
schema. All JAXB implementations provide a tool called a binding compiler to bind a
schema (the way the binding compiler is invoked can be implementation-specific).

xjc.sh ­p test.jaxb books.xsd ­d work

The ­p option identifies a package for the generated classes, and the ­d option identifies a
target directory. So for this command, the classes are packaged in test.jaxb within the
work directory.
Unmarshal the Document

Unmarshalling an XML document means creating a tree of content objects that represents
the content and organization of the document. The content tree is not a DOM-based tree.
In fact, content trees produced through JAXB can be more efficient in terms of memory
use than DOM-based trees.

To unmarshal an XML document, you:

Create a JAXBContext object. This object provides the entry point to the JAXB API.
When you create the object, you need to specify a context path. This is a list of one or
more package names that contain interfaces generated by the binding compiler. By
allowing multiple package names in the context path, JAXB allows you to unmarshal a
combination of XML data elements that correspond to different schemas.

For example, the following code snippet creates a JAXBContext object whose context
path is test.jaxb, the package that contains the interfaces generated for the books.xsd
schema:

• import javax.xml.bind.JAXBContext;

• JAXBContext jc = JAXBContext.newInstance("test.jaxb");

• Create an Unmarshaller object. This object controls the process of unmarshalling. In
particular, it contains methods that perform the actual unmarshalling operation. For
example, the following code snippet creates an Unmarshaller object:

• import javax.xml.bind.Unmarshaller;

• Unmarshaller unmarshaller = jc.createUnmarshaller();

• Call the unmarshal method. This method does the actual unmarshalling of the XML
document. For example, the following statement unmarshals the XML data in the
books.xml file:


• Collection collection= (Collection)
• unmarshaller.unmarshal(new File( "books.xml"));

Note that a
Collection here is a test.jaxb.Collection, not a
java.util.Collection.

• Use the get methods in the schema-derived classes to access the XML data. Recall
that the classes that a JAXB compiler generates for a schema include get and set
methods you can use to respectively obtain and specify data for each type of element
and attribute in the schema. For example, the following statement gets the data in the
books and book elements:

• CollectionType.BooksType booksType = collection.getBooks();
• List bookList = booksType.getBook();

After obtaining the data, you can display it directly from your program. Here, for
example, is a program that unmarshals the data in the books.xml file and then displays
the data. If you run the program, you should see the following result:
Book  details 
Item id: 999
Book Name: Learning JAXB
Book ISBN: 123445
Book Price: 34 $
Book category: other
Book promotion: 10% on this book if purchased by March 2003
No of Authors 1
Author Name Jane Doe

Book  details 
Item id: 129
Book Name: Java Webservices today and Beyond
Book ISBN: 522965
Book Price: 29 $
Book category: magazine
Book promotion: Buy one get Learning webservices Part 1 free
No of Authors 2
Author Name John Brown
Author Name Peter T.

Validating the Source Data: Notice that the program includes the following statement:

unmarshaller.setValidating(true);

This statement highlights an important feature of JAXB: you can have it validate the
source data against the associated schema as part of the unmarshalling operation. In this
case, the statement asks JAXB to
You can validate source data against an associated schema
validate the source data against as part of the unmarshalling operation.
its schema. If the data is found to
be invalid (that is, it doesn't conform to the schema) the JAXB implementation can report
it and might take further action. JAXB providers have a lot of flexibility here. The JAXB
specification mandates that all provider implementations report validation errors when
the errors are encountered, but the implementation does not have to stop processing the
data