Creating A Web Service From A Java Class

background image

Creating a Web service from a Java

class

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Table of Contents

If you're viewing this document online, you can click any of the topics below to link directly to that section.

1. About this tutorial

.......................................................

2

2. Introduction to RPC-style Web services

............................

7

3. Java API for XML-based RPC (JAX-RPC)

.........................

8

4. RPC Web service development life cycle

..........................

14

5. Lab 1: Building and deploying a Web service

.....................

17

6. Lab 2: Exchanging complex SOAP objects

........................

26

7. Lab 3: Dynamic Web service client

.................................

30

8. Tutorial wrapup and resources

.......................................

35

Creating a Web service from a Java class

Page 1 of 36

background image

Section 1. About this tutorial

Purpose of this tutorial

This tutorial delves into the subject of RPC-style Web services and how to use them with
IBM's WebSphere SDK for Web services V5.0 (WSDK). We show you how to write Web
service implementations, and how to build and deploy them with the WSDK, as well as
showing you how to create clients to invoke them.

In particular, we will demonstrate the ability of IBM's WSDK to exchange complex SOAP data
types. Although passing text strings and simple arrays is a good way to get you started with
Web services, real world applications typically require that client and service exchange whole
objects and similar complex data structures.

The tutorial begins with a brief examination of RPC-style Web services, followed by a section
on JSR-101, the Java API for XML-based RPC (JAX-RPC). We look at the architecture and
the most important API types for JAX-RPC. We also look at how static and dynamic
invocations work in the context of JAX-RPC.

Finally, a real-world application of these concepts is explored through three labs as a part of
our online DVD e-commerce store case study.

What you need to know for this tutorial

This tutorial assumes you have a working knowledge of Java programming and XML.
Knowledge of J2EE and Ant are helpful but not required. All of the example applications will
be deployed on IBM WebSphere Application Server that ships with the WSDK. Ant build
scripts are provided to make building and deploying the example applications easier and
more reliable. References to introductory material on Ant, Java programming, XML, IBM
WebSphere, and J2EE are provided in

Resources

on page 35 at the end of this tutorial.

What this tutorial covers

This tutorial explores the world of RPC-style Web services in depth. The following topics,
tools, and techniques will be covered:

Topics

Introduction to RPC-style Web services

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

Building and calling a Web service with IBM's WSDK

Building a dynamic Web services client with IBM's WSDK

Tools

Bean2WebService - Convert standard Java classes into Web services

JAX-RPC

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 2 of 36

Creating a Web service from a Java class

background image

Techniques

Building and deploying a Web service

Working with complex data types

Creating a dynamic Web service client

About the labs in this series

All of the tutorials in this series focus on an online DVD rental shop similar to

NetFlix

. The

use case we are addressing, Rental Recommendation, involves allowing users to submit
what category movie they would like to rent and, based on their rental history, the Web
service suggests other movies. In the first tutorial ("Introduction to Web services and the
WSDK"), we simply ran one of the sample Web services and didn't build anything. In this
second tutorial, we expand our exploration of working with Web services using three labs:

Lab 1: Building and deploying a Web service -- In this lab, we walk through the process
of building and deploying a simple service, rather than having one handed to you. We also
introduce the Bean2WebService script and demonstrate its use.

Lab 2: Working with complex data types -- With this lab, we move a step closer to
fulfilling the Rental Recommendation use case by returning a complex data structure
representing a DVD object.

Lab 3: Dynamic client - This client also exchanges complex data types with the service
created in the previous lab. In this case, however, the client uses a dynamic invocation as
opposed to a static stub.

About the authors

Lead author, this tutorial

Rick Hightower -- CTO,

LearningPatterns

Rick Hightower, Chief Technology Officer at LearningPatterns, is a published author with
multiple achievements, industry awards, and certifications. In addition to writing many
technical articles, Rick is co-author of the book Java Tools to Extreme Programming, an
Amazon.com best seller, that covers applying Extreme Programming to J2EE development
using Ant, JUnit, Cactus, and more. He recently released a book on Java/Python
programming that covers JFC, Swing, JDBC, Java Servlets, Applets, functional
programming, object-oriented programming, regular expressions, and so on.

Rick wrote a series of well-received tutorials on EJB 2.0 CMP CMR for IBM developerWorks.
Rick enjoys coding, development, instructing, mentoring, consulting, and speaking. Rick has
recently spoken at XP Universe, JDJ Edge East, Lone Star Software Symposium, and other
conferences on applying XP to J2EE, XDoclet, and EJB CMP/CMR/EJB QL. While working
at Intel, Rick wrote a chapter for the book Java Distributed Objects, comparing CORBA, RMI,
and DCOM development with Java technology.

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 3 of 36

background image

Prior to working at LearningPatterns, Rick held the position of Director of Development for a
major software development and consulting firm where he was responsible for building a
framework and applications built on top of J2EE. He initiated a study group in XP, Java Cert,
J2EE and Design Patterns, developed the corporate training initiative, and also guided the
career development and education of the entire technical staff. In a previous life, Rick worked
at Intel's Distributed Enterprise Architecture Lab (DEAL) focusing on Enterprise Java (EJB
technology, CORBA, and so on).

Other authors

David Fraser -- Senior Mentor and Instructor,

LearningPatterns

David Fraser, a Senior Instructor at LearningPatterns, teaches a wide range of courses,
including Java/J2EE technology (EJB technology, Java Servlets/JSP technology, JDBC
technology), XML, XSLT, Advanced XSLT, Web services, and OOAD, and has co-authored
LearningPatterns Java Servlets/JSP technology and Web services courses. He has also
lectured at numerous conferences including speaking on J2EE at CAWorld, and on Java
Performance and Java Enterprise Architecture at Software Development Expo. His main
area of interest is in building distributed Enterprise systems and he is now focusing on Web
services and their related technologies.

David has his Master's of Information Technology Education degree from Dalhousie
University and is a Sun Certified Java Programmer. Previously, David worked for the
American Intercontinental University in Atlanta. While there, he played a principal role in
designing the company's Java technology curriculum for all of its campuses, taught Java
programming, and developed Java technology-based educational tools.

Kyle Gabhart -- Senior Mentor and J2EE and Web Services Specialist,

LearningPatterns

Kyle Gabhart, Senior Mentor at LearningPatterns, is a highly-regarded advanced Java
programming, XML and Web services subject matter expert and mentor. Kyle is a popular
public speaker recognized for his enthusiasm and dynamic analysis and presentation of
emerging technologies.

In addition to writing two dozen technical articles both online and in print, he has contributed
to two books, Professional Java and XML and Professional EJB Development, both by Wrox
Press. Kyle is the founder of the Web Services Java Users Group based in Dallas, TX, and
he is a Founding Member of the Worldwide Institute of Software Architects where he serves
as the Subject Chair for Architectural Patterns. Kyle also served as the DevX Java Pro at
DevX.com for two years.

Currently Kyle is delivering a Web services mentoring program focused on white board
discussions and practical hands-on work focused on foundational technologies such as XML,
XSL/XSLT, and Xpath, as well as high-level Web services concepts such as SOAP, WSDL,
UDDI, ebXML, and .NET. Kyle works directly with the developers to transfer his real-world
knowledge of Web services application development. All labs are J2EE-centric, but all
solutions are fully interoperable with .NET services.

Kyle is a Sun Certified Java Programmer and an IBM Certified Solution Developer.

Peter Schmitz -- Enterprise Java Consultant and Instructor,

LearningPatterns

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 4 of 36

Creating a Web service from a Java class

background image

Peter Schmitz is an integral part of the core consulting, mentoring, and course development
team at LearningPatterns. Responsible for the development, testing, and maintenance of
many of the company's technology-centric suite of offerings, Peter combines his practical
programming skills and mentoring excellence to develop the highest quality educational
programs available.

Peter also contributes heavily to the development, maintenance, and delivery of
vendor-specific lines and unique educational offerings, often developed as custom solutions
for third party clients and partners. His technical focus includes developing programs and
projects focused around Java technology, EJB technology, J2EE, Java Servlets, JSP files,
IBM WebSphere 4.0, XML, Web services (SOAP, UDDI, etc.) and more.

Most recently Peter served as a consulting Technical Architect at ING Bank, where he was
responsible for maintaining and expanding the Technical Architecture for a Business
Services Framework based on XML, Java Servlets and EJB technology. In this project, he
used IBM WebSphere, the IBM MQ Series, VisualAge for Java, and a Relational database.
Peter has served as Project Leader, Technical Architect, Analyst, Mentor, and Senior
Software Engineer on a number of prior consulting engagements.

Jacob Weintraub -- Co-founder and Director of Services,

LearningPatterns

Jacob Weintraub, co-founder and Director of Services at LearningPatterns, has been working
in Object and Advanced Technologies since 1988. He began working with the beta release of
the Java programming language in 1995, and also authored one of the earliest Java
technology courses offered to the public.

Since that time, he has spearheaded LearningPatterns' work at the cutting edge of advanced
enterprise technologies. This has included teaching and mentoring businesses in topics such
as J2EE/EJB technology, Object-Oriented Analysis and Design, XML/XSLT, and now in Web
services. He has also lectured at numerous conferences and written articles for Java Report
and JavaWorld.

Following LearningPatterns' belief that the best teacher is an experienced programmer,
Jacob is a seasoned developer. His experience includes mentoring teams of programmers
on building EJB technology-based systems, the development of OO libraries for financial
systems, development of a CORBA IDL to C++ compiler, and research into the management
of Very Large Computer Networks using layered OO models with the Distributed Computing
and Communications Center at Columbia University.

Tools you will need for this tutorial

At a minimum, you will need a simple text editor, a browser, and a Java SDK 1.3 (included
with the WSDK) or higher to compile the examples. You will also need the IBM WebSphere
SDK for Web Services (WSDK). The WSDK can be found at

IBM WSDK information and

download

. You can also order free CDs, which include the WSDK as well as other IBM Web

services ready products such as WebSphere Studio from the

developerWorks Speed-start

Web services

program. The WSDK ships with its own Java SDK (1.3.1), and batch files and

programs for starting, stopping, and administrating the embedded WebSphere Application
Server that ships with the WSDK.

Although building and deploying applications by hand can be fun, all of the examples include

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 5 of 36

background image

Ant build scripts to build and deploy the Web services we will be creating. Ant can be found
at

Apache's Ant home page

.

It is recommended that you use an Interactive Development Environment (IDE) since there
are quite a few JAR files to manage. We used Eclipse, a freely-available IDE, to build the
sample applications. The Eclipse project files are included in the lab exercises zip file (see

Resources

on page 35 ). Since the Eclipse workbench is also the foundation for IBM's

WebSphere Studio Application Developer, the projects files are compatible with both Eclipse
and Application Developer. As long as you configure your environment as suggested you can
use the Eclipse project files without any additional work. Eclipse or Application Developer is
not required, but can be found at the following locations:

Eclipse Web site

and

IBM

WebSphere Studio Application Developer Web site

, respectively. There is no requirement to

use Eclipse or Application Developer, but they are fully functional IDEs that can make your
life easier in building and working with Web services projects.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 6 of 36

Creating a Web service from a Java class

background image

Section 2. Introduction to RPC-style Web services

RPC-style or document-style?

Web services represent a tremendous step forward in terms of standards-based distributed
computing. A Web service can be used to do everything from Web-enabling a legacy
application, to deploying an application that can be accessed by clients written in different
programming languages, to establishing an internal corporate repository of components to
reduce maintenance and duplication of code. In any of these contexts, a particular Web
service could be implemented as either an RPC-style Web service or a Document-style
service.

The distinction between RPC services and Document services comes down to a matter of
business model and overall technical architecture. Consider the following descriptions:

RPC-style Web services essentially expose your server-side functionality as a remote
object that is typically accessed via a local proxy object on the client side. This type of
service tends to be rather fine-grained, exposing an interface that closely approximates the
actual data structures used internally to represent information.

Document-style Web services are considerably less restrictive than RPC-style Web
services. The service consumes the entire body of a Document-style SOAP message and
parses it as a standard XML document. This type of service tends to be more
coarse-grained, exposing a very general interface that accepts any document that adheres
to a specified XML schema. This approach hides the internal representation of data and
business processes from the end user.

It is often easier to understand the distinction between these two service models by
comparing them at a high-level, in a feature-by-feature comparison, as shown in the following
table:

RPC-style

Document-style

Message body

Treated as a collection of
parameters

Processed as an arbitrary
document

Processing model

Parameters mapped to native
data structures

Parse XML based on an external
XML Schema

Invocation
mechanism

Method called on local proxy
object, routed directly to service
interface

Document published to server for
processing

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 7 of 36

background image

Section 3. Java API for XML-based RPC (JAX-RPC)

JSR-101: JAX-RPC

JSR-101 is the Java API for XML-based RPC (JAX-RPC). The objective of this JSR is to
create a specification and API that support the development of simple Web services and
Web service clients in such a way as to shield developers from the underlying complexity of
SOAP communication.

The JAX-RPC Expert Group has the following goals for the specification:

Simplicity

Interoperability across heterogeneous environments

Conformance with any interoperability standards

Extensibility and modularity

The WSDK has implemented JSR-101 in the tools, libraries, and supported APIs that ship
with the product. In fact, the sample in the first tutorial ("Introduction to Web services and the
WSDK") relied upon classes and libraries that implement JSR-101. In this tutorial we will
learn more about JAX-RPC, RPC-style Web services, and of course, the WSDK's support for
JSR-101.

Rather than overwhelm you with a lot of detail that you won't need to create simple
RPC-based Web services, we have split the discussion of RPC-style Web services across
three small tutorials (this one, "Creating a Web service from a Stateless Session Bean," and
"Describing Web Services: WSDL"). Once you complete this tutorial and "Creating a Web
service from a Stateless Session Bean", then you will be ready to dig deeper into WSDL and
some of the lower-level tools that come with the WSDK like WSDL2WebService. If you follow
along until then, you will have a deep practical knowledge of RPC-based Web services and a
strong foundation to master the rest of the tutorials in this series.

JAX-RPC architecture basics: Deja vu?

JAX-RPC, the Java API for XML-based RPC, is a specification for building Web service
providers and requesters. A requester is a client of a Web service. The requester can
perform remote method invocation against the client.

Deja vu, you say. Does this sound familiar? On the surface JAX-RPC looks like another
instantiation of RMI. In fact, in a way it is, but geared to Web services with some additional
limitations. Essentially, JAX-RPC allows clients to access a Web service as if the Web
service was a local object mapped into the client's address space even though the Web
service provider could be on the other side of the world.

However instead of IIOP or JRMP, as in the RMI world, in the JAX-RPC world a remote
method invocation (referred to as a remote procedure call) is done via the XML-based
protocol SOAP 1.1, which typically rides on top of HTTP. The SOAP protocol uses an
envelope structure that encodes method invocation data and method responses using XML
Schema and other encoding rules.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 8 of 36

Creating a Web service from a Java class

background image

Luckily, you do not have to worry about the low-level details and complexity of SOAP to use
Web services. The Web service provider developer can specify the remote procedures by
defining remote methods in a Java interface just like you do in RMI. From this interface you
generate a Web service description language file (WSDL file). From the WSDL file you can
generate a stub just like you would in RMI. Here's a very high view of how it all works
together:

The invocation above works like this:

The client invokes a method on a stub, a proxy which invokes routines in the JAX-RPC
runtime.

The JAX-RPC runtime converts the invocation into a SOAP message and transmits it
(usually over HTTP).

The server side receives it, and its JAX-RPC runtime translates the SOAP message into a
method invocation.

The JAX-RPC runtime invokes a method on the tie object, which delegates it to the actual
service implementation.

It returns the same way. The service implementation's response is translated into a SOAP
message, sent back to the client, where it gets translated and passed up the chain to the
client.

The Web service provider developer only needs to code one or more classes that implement
those methods just like the server-side RMI developer would create a servant. The rest of the
classes can be generated automagically by the Web service vendor's tools.

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 9 of 36

background image

Here's an example of a Web service interface that looks just like its RMI cousin (which we
will look at next):

package lpc.dvdonline.complexrpc.server;
import lpc.dvdonline.complexrpc.service.DVD;

public interface DVDOnlineStore_SEI extends java.rmi.Remote {

public DVD getDVD() throws java.rmi.RemoteException;

}

JAX-RPC datatypes and interface rules

Web services typically use XML Schema for creating strongly typed services. There are
standard type mappings from XML Schema to Java code. For example, a xsd:string in XML
Schema maps to java.lang.String. Don't worry about all of the details of this now. We will
touch on some of the details in this tutorial; just enough for you to get by. We cover WSDL,
XML Schema, and Java mappings in a lot of detail in the tutorial "Describing Web services:
WSDL." For now, let's cover the allowed types and rules for defining the interface, since
you'll need that to define your Web services properly.

You will recall our previous sample interface:

package lpc.dvdonline.complexrpc.server;
import lpc.dvdonline.complexrpc.service.DVD;

public interface DVDOnlineStore_SEI extends java.rmi.Remote {

public DVD getDVD() throws java.rmi.RemoteException;

}

Just like in RMI, the interface definition in JAX-RPC has to follow certain rules; most of these
rules are from RMI with some additions for JAX-RPC. Here are the rules for defining a
JAX-RPC interface:

1. The interface must extend

java.rmi.Remote

just like RMI.

2. Methods must throw

java.rmi.RemoteException

3. Method parameters must not be remote references (an addition to the regular RMI rules).

4. Method parameters must be one of the following:

Primitive Types: boolean, byte, double, float, short, int, and long

Object wrappers of primitive types: java.lang.Boolean, java.lang.Byte, java.lang.Double,
java.lang.Float java.lang.Integer, java.lang.Long, java.lang.Short

java.lang.String

java.lang.BigDecimal

java.lang.BigInteger

java.lang.Calendar

java.lang.Date

5. Methods may take value objects, which consist of a composite of the types mentioned

above plus aggregate value objects.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 10 of 36

Creating a Web service from a Java class

background image

Value objects are simple Java types that must follows certain rules, which we cover next.

Value objects

A value object is just a bean. It has to have getters and setters that will be mapped to XML
elements and attributes. Unlike plain RMI, the JavaBean does not have to be serializable, but
it does need a no-argument public constructor. The JAX-RPC implementation uses the getter
and setter methods to populate the bean. Here is an example of a value object:

package lpc.dvdonline.complexrpc.service;

public class DVD {

private String title; // unique id (primary key)
private int rank;
private String category;

public DVD() {

title = "no title";
rank = 0;
category = "no category";

} //end DVD()

public DVD(String _title, int _rank, String _category) {

title = _title;
rank = _rank;
category = _category;

} //end DVD( String, int, String )

public String getCategory() {

return category;

} //end getCategory()

public int getRank() {

return rank;

} //end getRank()

public String getTitle() {

return title;

} //end getTitle()

public void setCategory(String category) {

this.category = category;

} //end setCategory( String )

public void setRank(int rank) {

this.rank = rank;

} //end setRank( int )

public void setTitle(String title) {

this.title = title;

} //end setTitle( String )

} //end class DVD

JAX-RPC stubs and clients

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 11 of 36

background image

Let's look at the requester side now (the client code). The requester programs are easy to
build as well. A client creates a stub and invokes methods on it. The stub acts like a proxy for
the Web service. From the client code perspective, it seems like a local method invocation.
However, each method invocation gets marshaled to the remote server. This marshalling
includes encoding the method invocation in XML as prescribed by the SOAP protocol.

But wait! That's not all. In the JAX-RPC world the server does not have to be a Java server.
As long as you have a WSDL file, you can generate a stub and start invoking methods on the
Web service no matter what the platform or language. This is the beauty of Web services
and open standards like HTTP, SOAP, and WSDL. WSDL is an XML file format that
describes a Web service's locations, operations, and supported types. There will be more
detail about WSDL in the tutorial "Describing Web services: WSDL," which focuses on
WSDL.

If someone gives you a WSDL file that describes an RPC style Web service, you can run a
utility against that WSDL file to create a stub. A stub is a proxy object that has methods that
match the operations of the remote interface. Much of the details of WSDL and how it maps
to stub generation is hidden when you use tools like Bean2WebService, which is what we
use in this tutorial. We only talk about stubs and WSDL briefly in this tutorial and then go into
much more detail in the tutorial "Describing Web services: WSDL" when we cover the
WSDL2WebService utility.

Clients use stubs to simplify development of requesters of Web services, but they are not
really needed. You have the option of working with SOAP and JAX- RPC at a much lower
level. In addition to stubs, JAX-RPC provides a dynamic method invocation mechanism.

Static means that the generated code includes everything needed to invoke the service
directly, including interfaces that have the service methods defined as remote methods.

Dynamic means that you create the call dynamically, in a manner similar to reflection. In this
tutorial there are requester labs that use both the dynamic and static stub approaches.
Before we can look at all this though, we'll take a quick look at the JAX-RPC API.

JAX-RPC API classes of note

There are just a few key classes and interfaces that you need to be familiar with to write Web
service clients or service implementations. A good deal of it you don't even use directly.
Some of the important types are:

Service

interface: A factory for stubs or dynamic invocation/proxy objects that are used

to actually invoke methods

ServiceFactory

class: A factory for

Services

Call

interface: Used for dynamic invocation

Stub

interface: Base interface for stubs

If you are using a stub to access the Web service provider, then most of the details of the
JAX-RPC API are hidden from you. The client creates a

ServiceFactory

(

javax.xml.rpc.ServiceFactory

). From the

ServiceFactory,

the client instantiates

a

Service

(

javax.xml.rpc.Service

).

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 12 of 36

Creating a Web service from a Java class

background image

The

Service

is a factory object that creates the port. The port is a remote interface

(

java.rmi.Remote

) into the Web service. In the case of dynamic RPC, the

Service

object is used to create

Call

objects, which specify which method to call on the Web

services port.

The tutorial "Creating a Web service from a Stateless Session Bean" has labs that use a

ServiceFactory

with information about how to configure a

ServiceFactory

. The static

client labs in this tutorial cover using the

Service

object generated by the WSDK tools to

create a port object. The dynamic client lab in this tutorial covers using this

Service

class to

create a

Call

object.

The WSDK has utilities that generate all this code for you. This includes stub and service
types. The static examples in this lab use the generated service to create the stub (also
known as the port, or remote reference). The generated service has a factory method based
on the name of the port that returns a remote reference to the interface associated with the
port. Port is a fancy name for a Web service interface (more on this in the tutorial "Describing
Web services: WSDL").

There are two versions of this factory method. One of the versions takes no arguments and
will return the Service port at the URL location of the service (known as an endpoint). The
second version of the port factory method allows you to pass a different URL location for the
service. The first lab has a lab review that shows the generated

Service

for you to look at.

Remember to look for the two different port factory methods. A few lines of code are
sometimes worth a thousand words, and we'll be looking at that soon.

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 13 of 36

background image

Section 4. RPC Web service development life cycle

Introduction

The development life cycle for Web services is similar to that of traditional distributed
computing. Although the description given in this section is common to most Web service
implementations, the ideology and protocols upon which Web services are built allow
industry to continue to evolve the concept of "Web services." In short, what follows describes
the current state of the art and is not definitive. Also, this discussion assumes that there are
tools for the generation of the WSDL and skeletons/stubs. Although these tools are now
extremely common, there might be cases where the developer is responsible for the
stub/skeleton code.

The service

Creating and deploying an RPC-style Web service involves 5 steps:

1. Write the service implementation.

This is the class that actually implements the service. Usually the implementation would
already exist as some kind of server-side functionality that you want to expose.

Depending on the Web service tools you use, you might also need to create an interface
that defines the procedures of the service implementation that you want to expose. For
instance, the CreditCardProcessor might define 100 methods. How does a tool know
which of the 100 methods it should write supporting skeleton code for? There is probably a
subset of these 100 that are appropriate to expose. Most Web service technologies require
one to either create an interface or some other type of file that lists the methods to expose
or use meta tags in the implementation code to mark those methods that need to be
invocable as a Web service.

2. Generate the WSDL file that describes the service.

This is usually accomplished with a tool of some kind, although since it is an XML-based
protocol one can actually write a WSDL file using a simple text editor.

This step is not a requirement. However it is usually a good idea to create a WSDL file so
that clients can know how to invoke services. Also your client's Web service tools probably
use WSDL to generate the client's stub code.

A link to your service's WSDL file can be included in any description of your organization
or its services that appears in a registry.

3. Generate the support code (skeleton/tie) for the service implementation.

This is usually accomplished with a tool of some kind. This enables quicker integration with
existing systems, as the knowledge and time required to write the low-level code that
manages the socket communication and protocol stream generation is not required by the
developer.

Depending on the tool, this step might require you to compile the code generated. If you
are using Java code and this is the case, then you'll probably have to modify your
classpath to include whatever classes/interfaces are used in the generated code.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 14 of 36

Creating a Web service from a Java class

background image

4. Deploy implementation and support code.

This might require packaging all of the code, modifying a configuration file, and restarting a
server. Or it might only involve dropping the Web service code in a directory. In all cases
the server that is going to provide the Web service that is deployed needs to know about
your Web service and have access to its code. Different implementations will do this
differently.

5. Optionally, register your service with a registry provider.

To make it easier for people and processes to find and invoke your Web service, you might
want to register your Web service with a registry service. Registries, their purpose, and
how to communicate with them will be covered in two later tutorials in the series.

The client

Creating and running an RPC-style Web service client involves 4 steps:

1. Obtain the interface details of the Web service you want to invoke.

Usually this is accomplished by getting a WSDL file that describes the Web service that
you are interested in executing. You might acquire it from a registry, a Web site, or
someone giving it to you via e-mail or diskette for that matter.

WSDL seems to be the most popular way to pass Web service invocation information
around. However, a WSDL file is not required. If you can get the invocation particulars
(name of procedure, parameters, return type, url, and so on), you can write the code to
invoke a Web service.

2. Optionally generate Web service client invocation code (stubs).

Once you know the location (URL) of a Web service's WSDL file you can generate the
client stub code necessary for you to invoke it.

Most Web service technologies come with a tool for generating your stubs. Sometimes
they require you to give them generation properties such as target package, generated
class names, and so on.

This step is optional as there is usually a dynamic invocation API available where a stub is
not required to invoke a Web service.

3. Write the client.

The easiest way to write a client is to create or obtain a reference to a stub object and then
call its Web service-exposed methods.

If the stub is not available, or if you do not want to use it, most Web service technologies
come with an API that allows you to invoke the Web service of interest dynamically.

Compiling the client code will require that you have all the necessary support code (stub,
dynamic invocation api, and so on) in your classpath.

4. Run the client.

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 15 of 36

background image

To run the client, your Web service runtime's client code will need to be in your classpath.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 16 of 36

Creating a Web service from a Java class

background image

Section 5. Lab 1: Building and deploying a Web service

Lab purpose and overview

The purpose of this lab is to provide you with hands-on experience building, deploying, and
testing a Java Web service using IBM's WSDK. This lab will also demonstrate just how easy
the WSDK makes it to deploy existing Java classes as XML Web services.

The lab has three very simple steps:

1. Create a standard Java class and declare it to be accessible as a remote object

(implement the

Remote

interface, and have each remotely accessible method throw a

RemoteException

).

2. Package the class and deploy it as a Web service using a utility called

Bean2WebService

.

3. Create a client to test the service.

Building the service provider for a simple RPC-based
Web service

In this section you are going to create your first RPC-based Web service. You will create the
Web service implementation class here. It is purposely a very simple class. To create it,
perform the following steps:

1. Before creating the service, create a folder called simpleRPC directly underneath the

%WSDK_HOME%/apps directory.

2. Inside the simpleRPC directory, create a directory called provider.

3. In the provider directory, create a directory called src.

4. In the src directory, create a series of directories representing the package structure --

lpc.dvdonline.simplerpc.server.

5. Inside the lpc\dvdonline\simplerpc\server directory, create a Java source file called

DVDOnlineStore.java. Add the following code to that source file:

package lpc.dvdonline.simplerpc.server;

public class DVDOnlineStore implements java.rmi.Remote {

public String getDVD() throws java.rmi.RemoteException {

return "Fight Club";

}//end getDVD()

}//end DVDOnlineStore

6. Compile the above class, making sure that %WSDK_HOME%\appserver\lib\j2ee.jar is in

your classpath where %WSDK_HOME% is the directory where you installed the WSDK
version 5. Navigate to the src directory and use the standard

javac

command as follows:

javac -d . -classpath %WSDK_HOME%\appserver\lib\j2ee.jar

lpc\dvdonline\simplerpc\server\DVDOnlineStore.java

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 17 of 36

background image

Packaging, deploying, and starting the service

There is a lot that has to happen to turn this simple class into a Web service. Luckily, the
WSDK has tools that do this for you. To package and deploy your service, you need to do
only straightforward things:

1. Start the application server.

You can launch the application server from the start menu. The WSDK install created a
shortcut in the WSDK program group called Start Server, and you can use this to start the
server.

You can launch the WebSphere Application Server from the command line. It is in the bin
directory %WSDK_HOME%\bin\appserver start.

Start the Application Server. As the Application Server is loading, you'll see a few status
messages. Look for the message "Server server1 open for e-business."

2. Run the Bean2WebService utility.

This utility converts standard Java classes into Web services.

Note: Prior to invoking the tool, make sure that the WSDK's bin directory,
%WSDK_HOME%\bin, is in your path .

To run the utility, open a command prompt, navigate to the simpleRPC\server\src directory
(%WSDK_HOME%\apps\simpleRPC\server\src), and invoke the Bean2WebService utility
(with the command entered all on one line):

Bean2WebService -cp .;%WSDK_HOME%\appserver\lib\j2ee.jar -project

SimpleRPC -deploy lpc.dvdonline.simplerpc.server.DVDOnlineStore

The arguments we are using for Bean2WebService are as follows:

The

cp

flag declares a classpath for the utility.

The

project

flag defines a name for the EAR file and corresponding Web context.

The

deploy

flag declares that the resulting EAR (consisting of class files and deployment

descriptors) should be deployed to the application server and the service immediately
started.

Finally, the Java class to be deployed as a service is declared as the final parameter for
the script.

The result of running the tool is that a folder is created in the current directory with the same
name as the Web service project (as specified by the

project

flag on the command line).

The contents of that folder include Java class files and deployment descriptors for deploying
the Java class created earlier as a Web service in IBM's WSDK. All of these files are
contained in and appropriately organized in an EAR bearing the name of the project --
SimpleRPC.ear. You don't need to do anything with this EAR however; because the

deploy

flag was used earlier, it has already deployed the EAR to the server and stored a copy of the
EAR in an expanded format underneath the

appserver

directory. More detail about this

deployment process and deployment result will be provided later in the tutorial.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 18 of 36

Creating a Web service from a Java class

background image

3. Check your results.

Verify that the service was deployed by checking the server log files for the lack of errors
and by using the

appserver appstatus

command. The

appserver appstatus

command lists the installed enterprise application in the WebSphere Application Server,
along with their run status (running or stopped). Invoke

appserver appstatus

as

follows:

appserver appstatus

Look for the SimpleRPC application name in the list of installed enterprise applications.

4. Start the Web service.

Start the Web service using the

appserver startapp

command as follows:

appserver startapp SimpleRPC

This tells WebSphere to start the Web service associated with the enterprise application
SimpleRPC.

Creating the service client for SimpleRPC

Now that we have a service, we need a client. Creating a JAX-RPC client is very simple. It
requires just a few lines of code:

1. In the simpleRPC directory (%WSDK_HOME%\apps\simpleRPC), create a directory called

requester. This directory will house the client source.

2. In the requester directory, create a directory called src.

3. In the src directory, create a series of directories representing the package structure --

lpc.dvdonline.simplerpc.client.

4. Inside the package lpc\dvdonline\simplerpc\client directory, create a Java source file called

DVDOnlineStoreClient.java. Add the following code to that source file:

package lpc.dvdonline.simplerpc.client;

import lpc.dvdonline.simplerpc.server.*;
import lpc.dvdonline.simplerpc.server.*;

public class DVDOnlineStoreClient {

public static void main( String[] args ) throws Exception{

DVDOnlineStore_SEIService loc = new DVDOnlineStore_SEIServiceLocator();
DVDOnlineStore_SEI port = (DVDOnlineStore_SEI)loc.getDVDOnlineStore();
System.out.println( port.getDVD() );

} //end main()

} //end DVDOnlineStoreClient

Notice that the client creates a service. It uses an IBM specific type, a ServiceLocator, to
do this. From the service it accesses the port, that is, the interface of our Web service, and
then it invokes the

getDVD()

method. We'll see how to use the ServiceFactoy method of

getting a service in the next tutorial, "Creating a Web service from a Stateless Session
Bean."

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 19 of 36

background image

5. The client needs the stubs, interface, and locator classes that were generated with

Bean2WebService. Copy the files and directories from the SimpleRPC\client-side directory
( %WSDK_HOME%\apps\simpleRPC\provider\src\SimpleRPC\client-side) to the
requester\src directory.

6. At this point you are ready to compile. Compile the above class as before with the

following JAR files under %WSDK_HOME%\appserver\lib on your classpath:

j2ee.jar

axis.jar

qname.jar

jaxrpc.jar

wsdl4j.jar

xerces.jar

commons-discovery.jar

saaj.jar

commons-logging-api.jar

At this point, because there are so many JAR files to manage, we suggest using a Java
IDE like the freely available

Eclipse IDE

.

7. Run the client using the

java

command. Make sure you have the same JAR files on the

classpath that you used for the compile:

java -classpath ...

lpc.dvdonline.simplerpc.client.DVDOnlineStoreClient

8. If you are using the Eclipse IDE, just click the little "running man" icon on the toolbar.

If you see the response message of "Fight Club", then you have tested the service and it is
alive and working. Not too bad for an hour's work. You created, deployed, and started your
first Web service, then you wrote a client to invoke a method on the Web service.

Lab review

Let's review what you have done, and let's review what the Bean2WebService utility did for
you.

You created a Web service using a standard Java class. You did not define an interface and
create a binding or anything like that per se. The Bean2WebService tool took care of most of
the heavy lifting. Bean2WebService deployed your Web service as a J2EE Web application
bundled in a WAR file, bundled in an EAR file. You created a Web service client using a
static, pre-defined stub class.

Although you did not define an interface per se, the Bean2WebService created one for you
as follows:

package lpc.dvdonline.simplerpc.server;

public interface DVDOnlineStore_SEI extends java.rmi.Remote {

public java.lang.String getDVD() throws java.rmi.RemoteException;

}

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 20 of 36

Creating a Web service from a Java class

background image

If you have done RMI development, this interface looks identical to the type of interface you
would have created for your RMI servant.

The Bean2WebService tools also generates a service class, and a stub class. The service
class implements the

javax.xml.rpc.Service

interface.

javax.xml.rpc.Service

is

a factory of the generated stub. You can also create

Call

objects and use dynamic proxies

with this interface, and we will cover these when we cover the dynamic client later in this
tutorial. The

Service

class file that gets generated is the

DVDOnlineStore_SEIServiceLocator.java file listed below:

/**

* DVDOnlineStore_SEIServiceLocator.java
*
* This file was auto-generated from WSDL
* by the Apache Axis WSDL2Java emitter.
*/

package lpc.dvdonline.simplerpc.server;

public class DVDOnlineStore_SEIServiceLocator

extends org.apache.axis.client.Service
implements lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEIService {

// Use to get a proxy class for DVDOnlineStore
private final java.lang.String DVDOnlineStore_address

= "http://localhost:6080/SimpleRPC/services/DVDOnlineStore";

public java.lang.String getDVDOnlineStoreAddress() {

return DVDOnlineStore_address;

}

// The WSDD service name defaults to the port name.
private java.lang.String DVDOnlineStoreWSDDServiceName

= "DVDOnlineStore";

public java.lang.String getDVDOnlineStoreWSDDServiceName() {

return DVDOnlineStoreWSDDServiceName;

}

public void setDVDOnlineStoreWSDDServiceName(java.lang.String name) {

DVDOnlineStoreWSDDServiceName = name;

}

public lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEI

getDVDOnlineStore() throws javax.xml.rpc.ServiceException {

java.net.URL endpoint;

try {

endpoint = new java.net.URL(DVDOnlineStore_address);

}
catch (java.net.MalformedURLException e) {

return null; // unlikely as URL was validated in WSDL2Java

}
return getDVDOnlineStore(endpoint);

}

public lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEI

getDVDOnlineStore(java.net.URL portAddress)
throws javax.xml.rpc.ServiceException {

try {

lpc.dvdonline.simplerpc.server.DVDOnlineStoreSoapBindingStub _stub

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 21 of 36

background image

= new lpc.dvdonline.simplerpc.server.DVDOnlineStoreSoapBindingStub(
portAddress, this);

_stub.setPortName(getDVDOnlineStoreWSDDServiceName());
return _stub;

}
catch (org.apache.axis.AxisFault e) {

return null;

}

}

/**

* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/

public java.rmi.Remote getPort(Class serviceEndpointInterface)

throws javax.xml.rpc.ServiceException {

try {

if

lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEI.class.isAssignableFrom

(serviceEndpointInterface)) {

lpc.dvdonline.simplerpc.server.DVDOnlineStoreSoapBindingStub _stub =

new lpc.dvdonline.simplerpc.server.DVDOnlineStoreSoapBindingStub(
new java.net.URL(DVDOnlineStore_address), this);

_stub.setPortName(getDVDOnlineStoreWSDDServiceName());
return _stub;

}

}
catch (java.lang.Throwable t) {

throw new javax.xml.rpc.ServiceException(t);

}
throw new javax.xml.rpc.ServiceException(
"There is no stub implementation for the interface:

"

+ (serviceEndpointInterface == null ? "null" :
serviceEndpointInterface.getName()));

}

/**

* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/

public java.rmi.Remote getPort(javax.xml.namespace.QName portName,

Class serviceEndpointInterface)
throws javax.xml.rpc.ServiceException {

if (portName == null) {

return getPort(serviceEndpointInterface);

}
String inputPortName = portName.getLocalPart();
if ("DVDOnlineStore".equals(inputPortName)) {

return getDVDOnlineStore();

}
else

{

java.rmi.Remote _stub = getPort(serviceEndpointInterface);
((org.apache.axis.client.Stub) _stub).setPortName(portName);
return _stub;

}

}

public javax.xml.namespace.QName getServiceName() {

return new javax.xml.namespace.QName(
"http://server.simplerpc.dvdonline.lpc", "DVDOnlineStore_SEIService");

}

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 22 of 36

Creating a Web service from a Java class

background image

private java.util.HashSet ports = null;

public java.util.Iterator getPorts() {

if (ports == null) {

ports = new java.util.HashSet();
ports.add(new javax.xml.namespace.QName("DVDOnlineStore"));

}
return ports.iterator();

}

}

The generated Stub class implements the DVDOnlineStore_SEI interface
(lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEI interface). This is what the client uses
to invoke methods on our service's port object. It is listed as follows:

/**

* DVDOnlineStoreSoapBindingStub.java
*
* This file was auto-generated from WSDL
* by the Apache Axis WSDL2Java emitter.
*/

package lpc.dvdonline.simplerpc.server;

public class DVDOnlineStoreSoapBindingStub

extends org.apache.axis.client.Stub
implements lpc.dvdonline.simplerpc.server.DVDOnlineStore_SEI {

private java.util.Vector cachedSerClasses = new java.util.Vector();
private java.util.Vector cachedSerQNames = new java.util.Vector();
private java.util.Vector cachedSerFactories = new java.util.Vector();
private java.util.Vector cachedDeserFactories = new java.util.Vector();

public DVDOnlineStoreSoapBindingStub() throws org.apache.axis.AxisFault {

this(null);

}

public DVDOnlineStoreSoapBindingStub(

java.net.URL endpointURL, javax.xml.rpc.Service service)
throws org.apache.axis.AxisFault {

this(service);
super.cachedEndpoint = endpointURL;

}

public DVDOnlineStoreSoapBindingStub(javax.xml.rpc.Service service)

throws org.apache.axis.AxisFault {

if (service == null) {

super.service = new org.apache.axis.client.Service();

} else {

super.service = service;

}

}

private org.apache.axis.client.Call createCall()

throws java.rmi.RemoteException {

try {

org.apache.axis.client.Call _call =

(org.apache.axis.client.Call) super.service.createCall();

if (super.maintainSessionSet) {

_call.setMaintainSession(super.maintainSession);

}
if (super.cachedUsername != null) {

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 23 of 36

background image

_call.setUsername(super.cachedUsername);

}
if (super.cachedPassword != null) {

_call.setPassword(super.cachedPassword);

}
if (super.cachedEndpoint != null) {

_call.setTargetEndpointAddress(super.cachedEndpoint);

}
if (super.cachedTimeout != null) {

_call.setTimeout(super.cachedTimeout);

}
if (super.cachedPortName != null) {

_call.setPortName(super.cachedPortName);

}
java.util.Enumeration keys = super.cachedProperties.keys();
while (keys.hasMoreElements()) {

java.lang.String key = (java.lang.String) keys.nextElement();
_call.setProperty(key, super.cachedProperties.get(key));

}
return _call;

}
catch (java.lang.Throwable t) {

throw new org.apache.axis.AxisFault(

"Failure trying to get the Call object", t);

}

}

public java.lang.String getDVD() throws java.rmi.RemoteException {

if (super.cachedEndpoint == null) {

throw new org.apache.axis.NoEndPointException();

}
org.apache.axis.client.Call _call = createCall();
_call.setReturnType(new javax.xml.namespace.QName(

"http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class);

_call.setReturnQName(new javax.xml.namespace.QName("", "getDVDReturn"));
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("");
_call.setEncodingStyle(null);
_call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR,

Boolean.FALSE);

_call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS,

Boolean.FALSE);

_call.setOperationStyle("rpc");
_call.setOperationUse("literal");
_call.setOperationName(new javax.xml.namespace.QName(

"http://server.simplerpc.dvdonline.lpc", "getDVD"));

java.lang.Object _resp = _call.invoke(new java.lang.Object[] {});

if (_resp instanceof java.rmi.RemoteException) {

throw (java.rmi.RemoteException)_resp;

}
else {

try {

return (java.lang.String) _resp;

} catch (java.lang.Exception _exception) {

return (java.lang.String)

org.apache.axis.utils.JavaUtils.convert(_
resp, java.lang.String.class);

}

}

}

}

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 24 of 36

Creating a Web service from a Java class

background image

Note the implementation of the

getDVD()

method. We will use a similar technique when we

create the dynamic client in an upcoming lab. The Bean2WebService also created a WSDL
file. We will leave the coverage of the WSDL file for the WSDL tutorial, "Describing Web
Services: WSDL."

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 25 of 36

background image

Section 6. Lab 2: Exchanging complex SOAP objects

Lab overview

The purpose of this lab is to demonstrate the ability of IBM's WSDK to exchange complex
SOAP data types. Although passing Strings and simple arrays is a good way to get you
started with Web services, real-world applications typically require that client and service
exchange whole objects and similar complex data structures. Complex types are supported
by JAX-RPC and XML Schema.

Define a Java type to represent a DVD object

When SOAP was created, the idea was to provide a neutral mechanism for transporting
objects within a distributed and heterogeneous environment. That's where SOAP got its
name: Simple Object Access Protocol. To accomplish this, each side must have a native
object representation and then agree upon a neutral format to map with their native
representation. In our case, both client and server are Java code-based, so they will both use
the same native format, a Java class.

The

DVD

class is a basic Java bean with three fields: title (

String

), rank (

int

), and category

(

String

), along with the usual getters and setters.

1. Before creating the value object DVD, create a folder called complexRPC directly

underneath the %WSDK_HOME%\apps directory.

2. Inside the complexRPC directory, create a directory called shared. This value object is

going to be used by both the provider (server) and the requester (client).

3. In the shared directory, Create a directory called src.

4. In the src directory create a series of directories representing the package structure --

lpc.dvdonline.complexrpc.service.

5. Create a DVD.java file in the lpc/dvdonline/complexrpc/service package directory as

follows:

package lpc.dvdonline.complexrpc.service;

public class DVD {

private String title; // unique id (primary key)
private int rank;
private String category;

public DVD() {

title = "no title";
rank = 0;
category = "no category";

} //end DVD()

public DVD(String _title, int _rank, String _category) {

title = _title;
rank = _rank;
category = _category;

} //end DVD( String, int, String )

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 26 of 36

Creating a Web service from a Java class

background image

public String getCategory() {

return category;

} //end getCategory()

public int getRank() {

return rank;

} //end getRank()

public String getTitle() {

return title;

} //end getTitle()

public void setCategory(String category) {

this.category = category;

} //end setCategory( String )

public void setRank(int rank) {

this.rank = rank;

} //end setRank( int )

public void setTitle(String title) {

this.title = title;

} //end setTitle( String )

} //end class DVD

Compile the class as you would any other Java class. From the src directory:

javac lpc\dvdonline\complexrpc\service\DVD.java

.

Building the service provider for ComplexRPC

In this section you are going to create a Web service that returns complex types. Perform the
following steps:

1. Inside the complexRPC directory, create a directory called provider.

2. In the provider directory, Create a directory called src.

3. In the src directory create a series of directories representing the package structure --

lpc.dvdonline.complexrpc.server.

4. Inside the package lpc\dvdonline\complex\server package directory, create a Java source

file called DVDOnlineStore.java. Add the following code to that source file:

package lpc.dvdonline.complexrpc.server;

import lpc.dvdonline.complexrpc.service.DVD;

public class DVDOnlineStore implements java.rmi.Remote {

public DVD getDVD() throws java.rmi.RemoteException {

return new DVD("Fight Club", 10, "Weird but good");

}//end getDVD()

}//end DVDOnlineStore

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 27 of 36

background image

Notice how the above source is different than the last provider. The

getDVD()

method

returns an instance of the DVD value object class that we just created instead of a plain
old String.

5. Compile the above class, making sure that %WSDK_HOME%\appserver\libs\J2EE.jar is in

your classpath where %WSDK_HOME% is the directory where you installed the WSDK
version 5. You'll also need the root directory of the

DVD

class on your classpath. Navigate

to the src directory and use the standard

javac

command as follows:

javac -d . -classpath

%WSDK_HOME%\appserver\libs\J2EE.jar;..\..\shared\src

lpc\dvdonline\complexrpc\server\DVDOnlineStore.java

Packaging, deploying, and starting the service

This works exactly the same as it did in the previous lab. We will summarize the steps here,
but if you need more information, look at the previous lab.

1. Start the application server.

Start Server shortcut, or

appserver start

2. Run the Bean2WebService utility.

From the src directory run the following:

Bean2WebService -cp

.;%WSDK_HOME%\appserver\lib\j2ee.jar;..\..\shared\src -project

ComplexRPC -deploy lpc.dvdonline.complexrpc.server.DVDOnlineStore

3. Check your results.

appserver appstatus

4. Start the Web service.

appserver startapp ComplexRPC

Creating the service client for ComplexRPC

Now that we have a service, we need a client.

1. In the complexRPC directory (%WSDK_HOME%/apps/complexRPC), create a directory

called requester. This directory will house the client source.

2. In the requester directory, create a directory called src.

3. In the src directory create a series of directories representing the package structure --

lpc.dvdonline.complexrpc.client.

4. Inside the package lpc\dvdonline\complexrpc\client directory, create a Java source file

called DVDOnlineStoreClient.java. Add the following code to that source file:

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 28 of 36

Creating a Web service from a Java class

background image

package lpc.dvdonline.complexrpc.client;

import lpc.dvdonline.complexrpc.server.*;
import lpc.dvdonline.complexrpc.service.*;

public class DVDOnlineStoreClient {

public static void main( String[] args ) throws Exception{

DVDOnlineStore_SEIService loc = new DVDOnlineStore_SEIServiceLocator();
DVDOnlineStore_SEI port = (DVDOnlineStore_SEI)loc.getDVDOnlineStore();
DVD dvd = port.getDVD();
System.out.println(dvd.getTitle());

}//end main()

}//end DVDOnlineStoreClient

Notice that just as before, the client creates a service. From the service it accesses the
port, that is, the interface of our Web service, and then it invokes the

getDVD()

method.

This time the

getDVD()

method returns a

DVD

object instead of a

String

object.

5. The client needs the stub, interface, and locator classes that were generated with

Bean2WebService. Copy the files and directories from the ComplexRPC\client-side
directory ( %WSDK_HOME%\apps\complexRPC\provider\src\ComplexRPC\client-side) to
the requester\src directory.

6. At this point you are ready to compile. Compile the above class as before with the

following JAR files under %WSDK_HOME%\appserver\lib on your classpath:

j2ee.jar

axis.jar

qname.jar

jaxrpc.jar

wsdl4j.jar

xerces.jar

commons-discovery.jar

saaj.jar

commons-logging-api.jar

Hopefully you are not doing this by hand! Remember the

Eclipse IDE

.

7. Run the client with the

java

command.

If you see the response message of "Fight Club", congratulations!

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 29 of 36

background image

Section 7. Lab 3: Dynamic Web service client

Lab purpose and overview

In a perfect world, you would always be both the service provider and service requester
developer. And, if you were not both the service provider and service requester developer,
the service provider developer would be nice and supply you a WSDL file. Then you could
take this WSDL file and generate client stubs. (Note: there is a whole tutorial on working with
WSDL files to generate provider and requester code. The Bean2WebService has hidden a
lot of details of WSDL.)

However, the world is nowhere near perfect. And, service providers can develop
SOAP-based services without WSDL files. Sad but true. So how do you invoke these
services anyway? You use dynamic SOAP invocation.

There are three JAX-RPC classes you need to worry about for dynamic invocation as follows:

1.

javax.xml.namespace.QName

2.

javax.xml.rpc.Call

3.

javax.xml.rpc.Service

Service

is a factory class for

Call

objects. We use the

Service

to create a

Call

object.

Then we pass the

Call

object its endpoint URL so it knows where the service is located,

and its operation name. The operation name is identified with a

QName

. A

QName

represents

an element name that is within a namespace.

Let's step through this and show the code.

1. Import the needed classes:

import javax.xml.namespace.QName;

import javax.xml.rpc.Call;

import javax.xml.rpc.Service;

2. Create a

Service

factory object as follows:

Service service = (Service)

Class.forName("org.apache.axis.client.Service").newInstance();

3. Use the

Service

to create the

call

object:

Call call = (Call) service.createCall();

4. Set the URL location of the

Service

:

String endpoint =

"http://localhost:6080/SimpleRPC/services/DVDOnlineStore";

call.setTargetEndpointAddress(endpoint);

5. Invoke the

call

object:

Object [] arguments = new Object[0];

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 30 of 36

Creating a Web service from a Java class

background image

String dvdName = (String) call.invoke(arguments);

Creating the dynamic service client for SimpleRPC

Now that you get the idea of how to do it, let's actually write a dynamic client for the
SimpleRPC lab.

1. Inside the package lpc\dvdonline\simplerpc\client directory, create a Java source file called

DynamicDVDOnlineStoreClient.java. Add the following code to that source file:

package lpc.dvdonline.simplerpc.client;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;

/**

* @author Rick Hightower
*
*/

public class DynamicDVDOnlineStoreClient {

public static void main( String[] args ) throws Exception{

String endpoint =

"http://localhost:6080/SimpleRPC/services/DVDOnlineStore";

String namespaceURI = "http://server.simplerpc.dvdonline.lpc";

Service service = (Service)

Class.forName("org.apache.axis.client.Service").newInstance();

Call call = (Call) service.createCall();

call.setTargetEndpointAddress(endpoint);
call.setOperationName(new QName(namespaceURI, "getDVD"));

Object [] arguments = new Object[0];

String dvdName = (String) call.invoke(arguments);

System.out.println("Dynamic " + dvdName);

} //end main()

} // end DynamicDVDOnlineStoreClient

2. Notice that the client does not need the stubs, interface, and locator classes that were

generated with Bean2WebService.

3. At this point you are ready to compile. Compile the above class as before with the

following JAR files under %WSDK_HOME%\appserver\lib on your classpath:

j2ee.jar

axis.jar

qname.jar

jaxrpc.jar

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 31 of 36

background image

wsdl4j.jar

xerces.jar

commons-discovery.jar

saaj.jar

commons-logging-api.jar

4. Run the client with the

java

command. Make sure you have the same JAR files on the

classpath that you used for the compile.

If you see the response message of "Dynamic Fight Club", then you have earned your Web
services Kung Fu brown belt!

What about dynamic clients with complex types?

Fine, you say. Good and well, you can invoke Web services that return simple types and
have simple arguments, but what would happen if the Web service had complex types like
our complex example? Simply put: our dynamic example above would break. So far we have
managed to stick fairly close to doing dynamic things in a somewhat vendor-neutral fashion.
Once you start working with complex types, using the dynamic mechanism becomes more
vendor specific. Future versions of the JAX-RPC API will fix this.

That said, there are only three lines of vendor-specific code needed to register the serializers
and deserializers. With the IBM WSDK, you have to register custom serializer and
deserializers with the

Call

object and tell the

Call

object what its return type is. It is really

quite simple. For completeness, we will create a dynamic client for the complex example.

Creating the dynamic service client for ComplexRPC

1. Inside the package lpc\dvdonline\complexrpc\client directory, create a Java source file

called DynamicDVDOnlineStoreClient.java. Add the following code to that source file:

package lpc.dvdonline.complexrpc.client;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;

import lpc.dvdonline.complexrpc.service.DVD;
import org.apache.axis.encoding.ser.*;

/**

* @author Rick Hightower
*
*/

public class DynamicDVDOnlineStoreClient {

private static void registerDVDClassWithCallObject(Call call){

QName qName = new javax.xml.namespace.QName

("http://service.complexrpc.dvdonline.lpc", "DVD");

Class clazz = DVD.class;
call.setReturnType(new javax.xml.namespace.QName

("http://service.complexrpc.dvdonline.lpc", "DVD"), DVD.class);

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 32 of 36

Creating a Web service from a Java class

background image

/* These three lines Axis specific */
Class beansf = BeanSerializerFactory.class;
Class beandf = BeanDeserializerFactory.class;
((org.apache.axis.client.Call)call).registerTypeMapping(clazz,

qName, beansf, beandf, false);

}

public static void main( String[] args ) throws Exception{

String endpoint =

"http://localhost:6080/ComplexRPC/services/DVDOnlineStore";

String namespaceURI = "http://server.complexrpc.dvdonline.lpc";

Service service = (Service)

Class.forName("org.apache.axis.client.Service").newInstance();

Call call = (Call) service.createCall();
registerDVDClassWithCallObject(call);

call.setTargetEndpointAddress(endpoint);
call.setOperationName(new QName(namespaceURI, "getDVD"));

Object [] arguments = new Object[0];

DVD dvd = (DVD) call.invoke(arguments);

System.out.println("Dynamic DVD Title " + dvd.getTitle());

} //end main()

} //end DynamicDVDOnlineStoreClient

Notice that, just as before, the client creates a service. From the service it creates the

Call

object and registers the

DVD

class with the

Call

object as well as the custom

serializers and deserializers. Then it functions as before. The only difference is that the

call.invoke

method now returns a

DVD

object instead of a plain old

String

.

2. At this point you are ready to compile. Compile the above class as before with the

following JAR files under %WSDK_HOME%\appserver\lib on your classpath:

j2ee.jar

axis.jar

qname.jar

jaxrpc.jar

wsdl4j.jar

xerces.jar

commons-discovery.jar

saaj.jar

commons-logging-api.jar

3. Run the client with the

java

command.

If you see the response message of "Dynamic DVD Title Fight Club", congratulations! You
are a Web services Kung Fu master!

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 33 of 36

background image

Exercise for the industrious

Do you remember in the first tutorial ("Introduction to Web services and the WSDK") how we
used the TCPMonitor? Setup the TCPMonitor and watch the HTTP/SOAP conversation
between the provider and requester in both the simple and complex RPC examples.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 34 of 36

Creating a Web service from a Java class

background image

Section 8. Tutorial wrapup and resources

Tutorial review

In this tutorial, we've done the following things:

Learned about JSR-101/JAX-RPC

Learned how to use the WSDK tools to create RPC-style Web services

Created, deployed, and consumed a Web service using simple types

Created, deployed, and consumed a Web service using complex types

Created dynamic clients that used both simple and complex types

You now have a good start on actually developing with Web services. We've also shown that
it is quite possible to develop with Web services using the specifications and tools available
today. Some businesses are already using these kinds of Web services for integrating their
systems enterprise-wide and between companies. Web services are starting to become a
key technology in Enterprise Application Integration (EAI).

In later tutorials, we will explore more complex topics, such as integrating Web services with
EJB technology, generating Web services code from WSDL, and much more. We hope that
you had as much pleasure in reading this tutorial as we did in writing it.

Resources

Code:

Download all the source code in the

source code

.

Specifications:

JAX-RPC (JSR-101)

JSR-109 -- Implementing Enterprise Web services

SOAP 1.1

UDDI

WS-I Basic Profile

WSDL 1.1

Tools:

developerWorks Speed-start Web services

IBM WebSphere Studio Zone

IBM WebSphere Developer Domain

WSDL4J project

Apache Ant project

Eclipse Web site

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Creating a Web service from a Java class

Page 35 of 36

background image

Resources:

developerWorks Open source projects

developerWorks Web services zone

java.sun.com: The source for Java technology

J2EE Web site

The Java Web Services Tutorial: JAX-RPC

UDDI Web site

Web Services Interoperability Organization (WS-I)

Web Services Security Web site

XML.org Web site

Feedback

Please send us your feedback on this tutorial.

Colophon

This tutorial was written entirely in XML, using the developerWorks Toot-O-Matic tutorial
generator. The open source Toot-O-Matic tool is an XSLT stylesheet and several XSLT
extension functions that convert an XML file into a number of HTML pages, a zip file, JPEG
heading graphics, and two PDF files. Our ability to generate multiple text and binary formats
from a single source file illustrates the power and flexibility of XML. (It also saves our
production team a great deal of time and effort.)

You can get the source code for the Toot-O-Matic at

www6.software.ibm.com/dl/devworks/dw-tootomatic-p

. The tutorial

Building tutorials with the

Toot-O-Matic

demonstrates how to use the Toot-O-Matic to create your own tutorials.

developerWorks also hosts a forum devoted to the Toot-O-Matic; it's available at

www-105.ibm.com/developerworks/xml_df.nsf/AllViewTemplate?OpenForm&RestrictToCategory=11

.

We'd love to know what you think about the tool.

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Page 36 of 36

Creating a Web service from a Java class


Document Outline


Wyszukiwarka

Podobne podstrony:
[JAVA][Web services became more accessible]
dostęp do komponentów ejb przez usługi web services KDK342TYVWJFHS4WYW2AD3PRYEQV2AIB3XIXBCY
NIST Guide to Secure Web Services SP800 95
OReilly Programming Web Services with SOAP, OReilly Programming Web Services with SOAP
09 neugschwandtner web services knxsci06 website
Create SAP Web Service in 5 Minu
WROX C# Web Services Building Web Services with ASP NET and NET Remoting
Create Your Own Search Engine with PHP and Google Web Services
Web Service Testing
Web Services Business Objects And Component Model
Sun Tzu and the Project Battleground Creating Project Strategy from The Art of War
ASP NET Module 6 Using Web Services
Galileo Web Services Product Overview
Progressing from imitative to creative exercises
Next Gen VoIP Services and Applications Using SIP and Java
Java, Matrix, Public class MatrixMultiplication
Progressing from imitative to creative exercises

więcej podobnych podstron