J2ME Web Services J2ME Web Services What is a Web

Document Sample
J2ME Web Services J2ME Web Services What is a Web Powered By Docstoc
					J2ME Web Services
                What is a Web service?
 Any program that is callable by another program across the Web in
  a way that is:
  • platform-independent,
  • language-independent
  • object model-independent
 Use the next generation infrastructure standards:
  • XML (eXtensible Markup Language) is a well known standard for storing,
    carrying, and exchanging data. XML is standardized by the W3C.
  • SOAP (Simple Object Access Protocol) is a lightweight platform and
    language neutral communication protocol that allows programs to
    communicate via standard Internet HTTP. SOAP is standardized by the W3C.
  • WSDL (Web Services Description Language) is an XML-based language
    used to define web services and to describe how to access them. WSDL is a
    suggestion by Ariba, IBM and Microsoft for describing services for the W3C
    XML Activity on XML Protocols.
  • UDDI (Universal Description, Discovery and Integration) is a directory
    service where businesses can register and search for web services.
                    J2ME Web Services
 “If Web services are expanding within your enterprise, it might be
  time for you to look at all those mobile devices as potential clients
  of your Web services. Learn how to use the J2ME Web Service
  APIs to extend the enterprise to include J2ME devices with a
  simple example application.”, said Jim White on May 9, 2005
 In 2004, the Java Community Process approved and finalized JSR-
  172, the J2ME Web Services Specification.
 More recently, Sun and IBM have added implementations of this
  specification into their J2ME development environments.
 Some mobile products such as those running Symbian Series 60
  OS now come with this optional J2ME API.
 J2ME Web services are based on the general Web services
  architecture and specifications, but looking at them from strictly the
  client, or service consumer, vantage point, J2ME Web services
  consists of two optional packages:
  • One for remote service invocation (Java API for XML-based RPC or JAX-
    RPC)
  • One for XML parsing (Java API for XML Processing or JAXP).
                     J2ME Web Services
 By design, the packages are independent from one another;
  allowing for the use of one without the other.
 The APIs are meant to provide Web service access via profiles
  from either J2ME Connected Device (CDC) or Connected Limited
  Device Configurations (CLDC).
 To build and run the example, here is the list of tools you will need:
  • Sun's J2ME Wireless Toolkit 2.2: Sun's J2ME development toolkit provides
    build tools, utilities, and device emulators.
  • Tomcat 5.0 for Java WSDP: This Web container is based on Apache's
    Jakarta Tomcat. It implements the JSP and servlet specifications. While it is
    not intended for production use, it provides an easy-to-learn and use platform
    for hosting a Web service.
  • Java Web Services Developer Pack 1.6: A Web service toolkit that can be
    integrated with the Tomcat Web container (above) that will allow you to
    build and test Web services.
  • Apache Ant: A Java-based tool for building and deploying your Web service.
 Simply follow the instructions and install each product.
 Extract the sample code from the download file into your
  WTK22/apps directory.
                    Example Application
 Imagine you work for a large life insurance company.
  • Insurance agents are meeting potential clients all the time. Using their J2ME
    mobile phones, these agents want to be able to gather some simple personal
    facts about their clients (name, age, whether the client smokes, etc.).
  • They then want to send these facts off to the corporate office in order to get
    policy plans and quotes they can immediately share with their clients.
  • The example application in this article provides a Web service that serves up
    policy plans and a J2ME MIDlet that your insurance agents can use to access
    the Web service.
      Developing the Example Application
 The formula for developing this application can be divided into two
  parts:
   • developing the Web service
   • developing the J2ME MIDlet that accesses that Web service.
 The basic steps to create a Web service and deploy it to the Tomcat
  server are as follows:
  • Write the Web service interface class.
  • Write the Web service implementation class.
  • Write the associated descriptor files (all XML files).
  • Compile the service and generate Web services stubs/ties and WSDL file
    using tools provided with the Java Web Services Developer Pack.
  • Deploy the web service to the Tomcat serve
   Developing the Example Application
 With the Web service ready to provide information deployed and
  running, the basic steps to creating the J2ME Web service client
  are:
  • Use the generated WSDL file and the tools built into the Wireless Toolkit to
    generate the stubs and supporting code used by the MIDlet to access the Web
    service.
  • Code the MIDlet and associated classes using JAX-RPC to invoke the Web
    service and JAXP to process the SOAP message.
  • Build and test the MIDlet on the Wireless Toolkit emulator(s).
                       The Web Service
 Those familiar with RMI, EJB, or other forms of distributed
  application development probably recognize the first two steps in
  developing a Web service.
 The interface class declares the methods on the insurance policy
  Web service that clients (in this case J2ME clients) can invoke. The
  code for the Web service is located in the server subdirectory of the
  InsuranceQuote folder you downloaded and set up earlier.
 Take a look at the com.roaminginsurer.QuoteService code.
   It defines the protocol or contract by which the client and Web service
    communicate. In this case, the client calls the service, the getQuote method,
    with a client's name, age, marital status, number of children, salary, and
    smoking status.
   The Web service returns a string. The string is actually an XML document
    containing recommended life insurance policy information.
                     The Web Service
The Quote Web Service Interface:
package com.roaminginsurer;
import java.rmi.*;
public interface Quote extends Remote {
  String getQuote(String name, int age, boolean married, int
  number_of_children,
                   long salary, boolean smoker) throws RemoteException;
}
                      The Web Service
 The implementation of the Web service
  com.roaminginsurer.QuoteImpl can be found in can be found in
  Listing 2.
 This Web service is constructed on JAX-RPC. Note that the
  interface extends java.rmi.Remote and the service method throws
  java.rmi.RemoteException. These are indications that Web services
  are very RMI like.
  • The implementation class implements the
    javax.xml.rpc.server.ServiceLifecycle interface along with the Quote
    interface. By implementing the ServiceLifecycle methods, the Tomcat Web
    container can manage the Web service through the init and destroy methods.
 Inside the getQuote method, the XML document response is
  created. The method creates a DOM object tree. The Document
  Object Model (DOM) is an API for working with XML documents
  and the API is used here to create a tree of policy objects. Inside of
  the init method, a document factory is created.
                     The Web Service
The Quote Web Service Interface:
package com.roaminginsurer;
import java.rmi.*;
public interface Quote extends Remote {
  String getQuote(String name, int age, boolean married, int
  number_of_children,
                   long salary, boolean smoker) throws RemoteException;
}
                        The Web Service
 this.context = (ServletEndpointContext) context;
  factory = DocumentBuilderFactory.newInstance();
  try { builder = factory.newDocumentBuilder();
  } catch (ParserConfigurationException e)
  { builder = null; }
 Then, in the getQuote method, elements representing policies are attached to the
  document. Each element has attributes that contain the policy coverage amount
  and annual rate. Below is the code that creates the "Gold" policy.

  Element gold = document.createElement("Gold");
  gold.setAttribute("coverage",coverage + "");
  gold.setAttribute("cost",rate + "");
  root.appendChild(gold);
 The XML document must finally be converted to a string for
  transport to the client. This is accomplished in the toString method.
            Compiling the Web Service
 Three other descriptor files are required for completing the Web
  service and deploying it to Tomcat:
  • web.xml: The standard deployment descriptor describes how to deploy the
    components (in this case, the Web service component).
  • config.xml: An XML configuration file that describes the Web service.
  • jaxrpc-ri.xml: An XML configuration file that describes how to deploy the
    Web service.
 Tools in Sun's Java Web Services Developer Pack 1.6 use these last
  two files. When compiling the Web service,
   the interface and implementation classes must be compiled (good old javac)
   The wscompile tool, using information from the config.xml, generates the
    stubs, ties, and the Web Services Description Language (WSDL) file. Stubs
    and ties are the low-level classes that the server needs to communicate with a
    client. More information on the WSDL file will be provided later.
            Compiling the Web Service
• The download code contain Ant scripts (build.xml) for compiling,
  building, and deploying the Web service. In the server directory, a
  build.properties file contains the root directory location for Tomcat,
  the project directory, etc. Before using the ant script, edit the
  properties in the file listed below to match your environment.
tomcat-root=C:/tomcat50-jwsdp
jaxrpc-root=${tomcat-root}/jaxrpc
j2ee-root=${tomcat-root}/jwsdp-shared
project-root=C:/WTK22/apps/InsuranceQuote/server
 To compile the Web service, simply call on Ant with the following
  directive:
ant compile
 If all goes well, you should see the generated stubs and ties in a
  subdirectory of the server directory called generated and the
  compiled code in the WEB-INF subdirectory. The WSDL file
  should also be available in the WEB-INF/classes subdirectory.
            Compiling the Web Service
• The download code contain Ant scripts (build.xml) for compiling,
  building, and deploying the Web service. In the server directory, a
  build.properties file contains the root directory location for Tomcat,
  the project directory, etc. Before using the ant script, edit the
  properties in the file listed below to match your environment.

tomcat-root=C:/tomcat50-jwsdp
jaxrpc-root=${tomcat-root}/jaxrpc
j2ee-root=${tomcat-root}/jwsdp-shared
project-root=C:/WTK22/apps/InsuranceQuote/server
            Compiling the Web Service
• Before compiling the service, take a look at the call to the
  wscompile tool in the ant script.
<wscompile server="true" keep="true" features="wsi,documentliteral"
  xPrintStackTrace="true" verbose="true" base="${classes.dir}"
  model="${web.dir}/model.gz" classpath="${web.dir}"
  config="${src.dir}/config.xml">
  <classpath>
   <path refid="compile.classpath"/>
 </classpath>
</wscompile>
• A very important argument to the wscompile task is the list of
  features to be enabled; namely wsi and documentliteral. As the
  JAX-RPC API for J2ME only supports the literal representation of
  a SOAP message (no XML encoding), these features will allow a
  J2ME client to communicate with the service.
Building and Deploying the Web Service
 The last steps to provide this Web service is to build the .war file
  and deploy it to the server.
 As part of the build process, you will use the second of two tools,
  wsdeploy tool reads a .war file and the jaxrpc-ri.xml file and
  subsequently generates another WAR file that is ready for
  deployment. Run the following Ant directives to build your war file
  (and have wsdeploy rebuild the file) and deploy the war file to the
  Tomcat server. In the Ant script I have provided, the deploy task
  will also start Tomcat with the new web service running in it.
ant build
ant deploy
 To test whether your service has been properly built and deployed,
  you should be able to open a browser and enter the following
  http://localhost:8080/quoteservice/quoteservice in the address
  field.
 Overview of Invoking Web Services
 Invoking a Web service refers to the actions that a client
  application performs to use the Web service. Client applications
  that invoke Web services can be written using any technology:
  Java, Microsoft SOAP Toolkit, Microsoft .NET, and so on.
 The Java API for XML based RPC (JAX-RPC) is a Sun
  Microsystems specification that defines the client API for invoking
  a Web service. The following table briefly describes the core JAX-
  RPC interfaces and classes.
  • Service: Main client interface. Used for both static and dynamic invocations.
  • ServiceFactory: Factory class for creating Service instances.
  • Stub: Represents the client proxy for invoking the operations of a Web
    service. Typically used for static invocation of a Web service.
  • Call: Used to dynamically invoke a Web service.
  • JAXRPCException: Exception thrown if an error occurs while invoking a
    Web service.
             J2ME Web Service Client
 With the Web service in place, you can now focus on the J2ME
  application that will call on the Web service. For this, you will need
  Sun's J2ME Wireless Toolkit, as it offers an important tool to
  create the necessary client side stubs and test your J2ME
  application's communications with the Web service through device
  emulators.
 Open the Wireless Toolkit and request to Open Project. If you have
  placed the code provided into the apps directory of the Wireless
  Toolkit's root directory, then InsuranceQuote should be one of the
  projects listed. Open the InsuranceQuote project. .
      Generating J2ME Client Side Stubs
 The WSDL file generated for building the Web service is going to
  be used by the Wireless Toolkit to generate the client-side stub
  code used by your MIDlet to access the Web service. This stub is a
  class that is a local Java object that acts as a proxy for the Web
  service instance. Your MIDlet makes a local method call to the stub
  and the stub, in turn, calls the Web service on the server.
• Open the WSDL file with your favorite text or XML editor. It
  should be in your [WTK22]\apps\InsuranceQuote\server\WEB-
  INF\classes directory. The wscompile tool generated the WSDL
  and left you with one job. You must change the last line of the
  WSDL file to specify the actual address location of your service.
• Change:
<soap:address
  location="REPLACE_WITH_ACTUAL_URL"/></port></service></definitio
  ns>
To:
<soap:address
  location="http://localhost:8080/quoteservice/quoteservice"/></port></servi
  ce></definitions*gt;
            The MIDlet User Interface
• Now you have a Web service and the client-side classes necessary
  to communicate with the Web service. On to developing the
  MIDlet application!
• The MIDlet provided as part of this sample application uses a
  J2ME MIDP Form and a List screen (both from the
  javax.microedition.lcdui package) to drive the user interface. The
  MIDlet uses an instance of the form EntryForm to collect client
  information that the MIDlet will pass to the Web service (see
  Listing 3). The EntryForm as seen on an emulator screen is shown
  in Figure 3.
• The MIDlet uses a List called PolicyList (see Listing 4) to display
  the policies returned by the Web service (see Figure 4).
• When the insurance agent selects one of the policy quotes from
  PolicyList, an instance of javax.microedition.lcdui.Alert is used to
  display the policy information (see Figure 5). The entire MIDlet
  user interface navigation is modeled in Figure 6.
Calling the Web Service with J2ME JAX-
                 RPC
 All that is left to do is to build and test your MIDlet. The Wireless
   Toolkit makes this easy. Simply push the Build button on the tool
   bar, fix any compile errors, and then push the Run button to
   execute your MIDlet in the emulator selected. Make sure your Web
   service in Tomcat is still up and running so that it can respond to
   the J2ME client's request.
 In the commandAction method of the GetQuoteMIDlet, when the
   user has hit the GetQuote command, the first of the two methods is
   invoked. Namely, the MIDlet calls the requestQuote method.
if (label.equals("Get Quote")) {
   requestQuotes();
}
 The requestQuote method collects all the client data out of the
   EntryForm and then requests to start a separate GetQuoteMIDlet
   thread.
new Thread(this).start();
Calling the Web Service with J2ME JAX-
                 RPC
 You might have noticed that the GetQuoteMIDlet implements the
  Runnable interface. Why does requestQuote start a new thread? If
  the operation was done in the commandAction method or other
  MIDlet method, then the MIDlet would have to wait for the Web
  service to respond. This could end up blocking the main Event
  Loop and other operations. Putting the call to the Web service in its
  own thread allows the MIDlet to continue to respond to the user (to
  answer the phone for example). In fact, if you place the call to the
  Web service in the same thread, you get the following warning
  when you run your application:
Warning: To avoid potential deadlock, operations that may block, such as
 networking, should be performed in a different thread than the
 commandAction() handler.
 As the GetQuoteMIDlet implements the Runnable interface, it is in
  the run method creates an instance of the Web service stub class
  you generated earlier (Quote_Stub), sets up some properties on that
  instance, and makes a call to the Web service.
Calling the Web Service with J2ME JAX-
                 RPC
try {
  service = new Quote_Stub();
  service._setProperty(Quote_Stub.SESSION_MAINTAIN_PR
  OPERTY, new Boolean(true)); String xmlStr =
  service.getQuote(name, age, married, children, salary,
  smoker); parseQuotes(xmlStr);
} catch (Exception exception) {
  Alert serviceProblem = new Alert("Service problem","Try
  your request later",null, AlertType.ERROR);
  serviceProblem.setTimeout(Alert.FOREVER);
  display.setCurrent(serviceProblem, form);
}
Calling the Web Service with J2ME JAX-
                 RPC
 Because of the potential for a remote exception (remember the RMI
  RemoteException that was part of the Web service interface?), the
  call is wrapped in a try catch block. A small part of the java.rmi
  package has been bundled with JAX-RPC just for this purpose.
  Where else do you see JAX-RPC here? If you look at the generated
  code, the Quote_Stub class implements the Stub interface from
  JAX-RPC and the other classes and methods are also from the
  J2ME JAX-RPC package
         Parsing the XML Using JAXP
 Once the Web service has been called and the J2ME application
  has received the XML document (in the form of a string), the
  MIDlet will take advantage of the second Web service API, the
  JAXP API, to parse the XML and offer the life insurance client
  some information about policies.
 Most of the parsing work in the sample application is done in the
  parseQuote method of the MIDlet. This method is called by the run
  method and is sent the string received in the Web service. It sends
  the XML string to a SAX parser and Handler to extract the element
  data out of the XML document into POJOs (plain old Java
  objects—in this case InsuranceQuote Java objects).
 An instance of com.roaminginsurer.QuoteParserHandler (which
  inherits from org.xml.sax.helpers.DefaultHandler) were created
  with the MIDlet initialization in the startApp method.
         Parsing the XML Using JAXP
parserHandler = new QuoteParserHandler();
try {
  SAXParserFactory factory = SAXParserFactory.newInstance();
  saxParser = factory.newSAXParser();
} catch (Exception e)
{
 The SAXParser and superclass DefaultHandler are both from the
  JAXP API. When the XML document is received the parser and
  handler are engaged to extract data from the document.
parserHandler.reset();
saxParser.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")),
  parserHandler);
 The SAXParser (SAX stands for Simple API for XML Parsing)
  reads the XML document and detects the beginning and end of the
  document, start and end of each element in the document, and so
  on. As it detects or parses the parts of the document, it calls on the
  associated handler instance to do something with the information
  located.
         Parsing the XML Using JAXP
 As seen in Listing 6, the QuoteParserHandler overrides the
  DefaultHandler's startElement method. As the SAXParse detects
  the start of each new element (in this case the start of each new
  policy quote) it puts the element's attribute information into a plain
  old Java object (POJO).
 The POJOs are collected and then passed on to the displayQuote
  method where the policies are listed in the List screen and the
  details are shown in an Alert screen when requested by the user.
displayQuotes(parser.getQuoteObjects());
      Building and Running the MIDlet
 Building and Running the MIDlet
  • Push the Build button on the toolbar, fix any compile errors, and then push
    the Run button to execute your MIDlet in the emulator selected.
  • Make sure your Web service in Tomcat is still up and running so that it can
    respond to the J2ME client's request.
 The J2ME Web services APIs (JAX-RPC and JAXP) are the subset
  of the enterprise versions of these packages. J2ME devices, are
  limited and so are the Web service features they can support.
                 Limited Functionality
 Below is a list of some of those limitations and features the current
  implementations do not support.
  • No support for service endpoints (no J2ME device based web services—only
    clients).
  • No service discovery support (UDDI).
  • Validating parsers are not required given memory and processor needs.
  • SOAP 1.1 encoding is not supported.
  • SOAP messages with attachments are not supported.
  • SOAP message handlers are not supported.
  • XSLT is not supported.
  • DOM is not supported.
  • No support for dynamic proxies or dynamic invocation interface (DII).