J2EE 1.4 APIs For Web Services by czz18476

VIEWS: 12 PAGES: 90

									J2EE 1.4 APIs For
   Web Services
     Michael D. Thomas
   mdthomas@ibiblio.org
Agenda
   Quick Tour Of J2EE APIs
   Service Oriented Architecture
   SOAP & WSDL: The 10 minute guide
   JAX-RPC
   SAAJ
   JAXP
   JAXR
A Simple Example
    Company has web app that looks up invoices
    The customers like it
    Customer wants to pass the data automatically to
     another application
    Typical situation for a web service
    Will do it with:
    1.   Straight XML (JAXP)
    2.   SAAJ: Wrapper around SOAP and HTTP
    3.   JAX-RPC: Uses SOAP and WSDL, but you never have
         to see it
Invoice Screen
Invoice App Structure
Invoice JSP
<html>
 <head>
  <title>Invoice</title>
 </head>
 <body bgcolor="white">
 <%@ page language="java"
          import="org.ibiblio.mdthomas.ws.autopartssupplier.*" %>
 <jsp:useBean id="invoiceHelper"
    scope="request"
    class="org.ibiblio.mdthomas.ws.autopartssupplier.InvoiceHelper"/>
 <jsp:setProperty name=”invoiceHelper”
                  property=”*”/>
 <%
 InvoiceBean invoice = invoiceHelper.getInvoiceById();
 CustomerBean customer = invoice.getCustomer();
 InvoiceItemBean items[] = invoice.getInvoiceItems();
 %>

Continued . . . .
Invoice JSP
<% for (int i=0; i<items.length;i++) { %>
      <tr>
       <td><%= items[i].getName() %></td>
       <td><%= items[i].getProductId() %></td>
       <td><%= items[i].getQuantity() %></td>
       <td align="right">
        <%= items[i].getPerItemPrice() %>
       </td>
       <td align="right">
        <%= items[i].getTotalLineItemPrice() %>
       </td>
      </tr>
      <% } %>

Continued . . . .
Invoice Helper
package org.ibiblio.mdthomas.ws.autopartssupplier;
import java.rmi.Remote;
import java.rmi.RemoteException;
public class InvoiceHelper {

    long id;
    InvoiceBusinessDelegate invoiceBusinessDelegate;

    public InvoiceHelper () {
     invoiceBusinessDelegate =
      BusinessDelegateFactory.getInvoiceBusinessDelegate();}

    public void setInvoiceId (long id) {
      this.id = id; }

    public long getInvoiceId() {
      return id;}
    public InvoiceBean getInvoiceById() {
      return invoiceBusinessDelegate.getInvoiceById(this.id);}

    public InvoiceBean getInvoiceById(long id) {
      return invoiceBusinessDelegate.getInvoiceById(id);}
}
InvoiceBean (incomplete)
package org.ibiblio.mdthomas.ws.autopartssupplier;

public class InvoiceBean implements Serializable {
  private CustomerBean customer;
  private InvoiceItemBean invoiceItems[];
  private long invoiceId;
  private float total;
  private float shippingCharge;
  private float subTotal;

    public InvoiceBean() {}
    public float getTotal() {
      return total;}
    public void setTotal(float total) {
      this.total = total;}
    public void setCustomer(CustomerBean customer) {
      this.customer = customer;}
    public CustomerBean getCustomer() {
      return customer;                               }
    public InvoiceItemBean[] getInvoiceItems() {
      return invoiceItems;}
    public void setInvoiceItems(InvoiceItemBean items[])   {
      this.invoiceItems = items;}
}
New XML Architecture
XML Invoice
XML Invoice JSP
<?xml version="1.0"?>
<ordering:invoice
   xmlns:ordering="http://www.tinasautoparts.com/xmlns/orders">
<%@ page language="java"
   import="org.ibiblio.mdthomas.ws.autopartssupplier.*" %>
<jsp:useBean id="invoiceHelper"
     scope="request"
     class="org.ibiblio.mdthomas.ws.autopartssupplier.InvoiceHelper"
   />
<jsp:setProperty name="invoiceHelper" property="*"/>
<%
    InvoiceBean invoice = invoiceHelper.getInvoiceById();
    CustomerBean customer = invoice.getCustomer();
    InvoiceItemBean items[] = invoice.getInvoiceItems();
%>
 <ordering:invoiceId>
  <%= invoice.getInvoiceId() %>
 </ordering:invoiceId>
Continued . . .
“Web Services” Requestor
public static void main(String[] args) throws Exception {
  long invoiceId = 0;
  if (args.length>0) {
    invoiceId = Long.parseLong(args[0]);}

    // Create the URL and encode the invoiceId param
    String base =
         "http://localhost:8080/jsp-examples/ch03/invoiceAsXml.jsp?";
    String invoiceParam = "invoiceId="+invoiceId+"&";
    URL invoiceURL = new URL(base+invoiceParam);

    // Connect to the URL
    URLConnection conn = invoiceURL.openConnection();
    conn.connect();

    // Get the result and create the XML
    InputStream invoiceStream = conn.getInputStream();
    DocumentBuilderFactory dbf =
         DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(invoiceStream);

    // Handle the XML
    handleXML(doc);
}
“Web Services” Requestor
private static void handleXML(Document doc) {

   float invoiceTotal = 0f;
        int totalQuantities = 0;
        float shippingCharge =0f;
   Element docRoot = doc.getDocumentElement();

   NodeList children = docRoot.getChildNodes();
   for (int i=0;i<children.getLength();i++) {
      Node node = children.item(i);
          System.out.println("node name: "+node.getNodeName());
      short nodeType = node.getNodeType();
      if (node.getNodeName().equals("ordering:customer")) {
          Element customerElement = (Element)node;
          NodeList nodeList =
           customerElement.getElementsByTagName("ordering:customerName");
      Element customerNameElem = (Element)nodeList.item(0);
      Node customerNameText = customerNameElem.getFirstChild();
          String customerName = customerNameText.getNodeValue();
          System.out.println("Customer name: "+customerName);
    }
Continued . . .
Basic XML Web Services
Issues
   Satisfies the business requirement
   Not standards based – doesn’t use SOAP or
    WSDL
   Had to handle HTTP directly
SAAJ & SOAP Approach
   Uses SOAP standard
   Similar to previous example, but requestor
    handles SOAP details
   SOAP: data (Body) and meta-data (Header)
   Contained in a SOAP envelope
   Can attach data outside of the SOAP
    envelope
   SAAJ: handles HTTP requests, wraps JAXP
    in SOAP specific nature (like JDOM)
SOAP Request
POST /invoice-jaxrpc/invoice HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: 246
SOAPAction: ""
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.4.2
Host: localhost:9090
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <getInvoiceById
   xmlns="http://www.ibiblio.org/mdthomas/invoice/types">
   <long_1 xmlns="">9845</long_1>
  </getInvoiceById>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP Request
POST /invoice-jaxrpc/invoice HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: 246
SOAPAction: ""
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.4.2
Host: localhost:9090
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <getInvoiceById
   xmlns="http://www.ibiblio.org/mdthomas/invoice/types">
   <long_1 xmlns="">9845</long_1>
  </getInvoiceById>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP Request
POST /invoice-jaxrpc/invoice HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: 246
SOAPAction: ""
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.4.2
Host: localhost:9090
Accept: text/html, text/xml, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
  <getInvoiceById
   xmlns="http://www.ibiblio.org/mdthomas/invoice/types">
   <long_1 xmlns="">9845</long_1>
  </getInvoiceById>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP Response (incomplete)
HTTP/1.1 200 OK
X-Powered-By: Servlet/2.4
SOAPAction: ""
Content-Type: text/xml; charset="utf-8"
Transfer-Encoding: chunked
Date: Sun, 23 Nov 2003 16:00:17 GMT
Server: Sun-Java-System/JWSDP-1.3

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:ns0="http://www.ibiblio.org/mdthomas/invoice/types">
 <env:Body>
  <ns0:getInvoiceByIdResponse>
   <result>
    <customer>
    data
    </customer>
    <invoiceId>9845</invoiceId>
    <invoiceItem>
     data
    </invoiceItem>
   continued…
SAAJ Provider
public class InvoiceSAAJProvider extends HttpServlet {
    MessageFactory messageFactory;
    public void doPost (HttpServletRequest request,
                       HttpServletResponse response)
                 throws ServletException, IOException {
      response.setContentType("text/xml");
      response.setBufferSize(8192);
      OutputStream out = response.getOutputStream();
      try {
         // initialize the messageFactory
      messageFactory = MessageFactory.newInstance();
      // Get the requested invoice
      long invoiceId = getInvoiceId(request);
      InvoiceHelper invoiceHelper = new InvoiceHelper();
      InvoiceBean invoice = invoiceHelper.getInvoiceById(invoiceId);

            // Create the SOAP output message
        SOAPMessage outputMessage = createOutputSOAPMessage(invoice);
            // Write the output SOAP message to the response output stream
        outputMessage.writeTo(out);

          } catch (Exception ex) {
              ex.printStackTrace();
          }
        out.close();
    }
SAAJ Provider
private long getInvoiceId(HttpServletRequest request) throws
               SOAPException, IOException {
  // create the input SOAP message from the request's inputStream
  MimeHeaders mimeHeaders = getMimeHeaders(request);
  InputStream inputStream = request.getInputStream();
  SOAPMessage inputMessage =
      messageFactory.createMessage(mimeHeaders,inputStream);

    // get the SOAP body
    SOAPPart inputPart = inputMessage.getSOAPPart();
    SOAPEnvelope inputEnvelope = inputPart.getEnvelope();
    SOAPBody inputBody = inputMessage.getSOAPBody();
    // get the invoice id as a String
    Name getInvName = inputEnvelope.createName("getInvoiceById",
                          null,
                         "http://www.ibiblio.org/mdthomas/invoice/types");
    Iterator it = inputBody.getChildElements(getInvName);
    SOAPElement getInvoiceElem = (SOAPElement)it.next();
    Name idName = inputEnvelope.createName("long_1"));
    it = getInvoiceElem.getChildElements(idName);
    SOAPElement invoiceIdElem = (SOAPElement)it.next();

    // convert to a long and return
    String invoiceIdStr = invoiceIdElem.getValue();
    long invoiceId = Long.parseLong(invoiceIdStr);
    return invoiceId;
}
Creating output
private SOAPMessage createOutputSOAPMessage(InvoiceBean invoice)
            throws SOAPException {
// Create a message
  SOAPMessage outputMessage = messageFactory.createMessage();
  SOAPPart outputSoapPart = outputMessage.getSOAPPart();
  SOAPEnvelope outputEnvelope = outputSoapPart.getEnvelope();
  outputEnvelope.addNamespaceDeclaration("ns0",
         "http://www.ibiblio.org/mdthomas/invoice/types");

 // Get the SOAP header from the message and remove it
 SOAPHeader header = outputMessage.getSOAPHeader();
 header.detachNode();
 // Get the SOAP body from the message
 SOAPBody body = outputMessage.getSOAPBody();

 // Add the top level elements
 Name responseName = outputEnvelope.createName(
                            "getInvoiceByIdResponse",
                            "ns0",
                            null);
 SOAPElement invoiceElem = body.addBodyElement(responseName);
 SOAPElement resultElem = invoiceElem.addChildElement("result");

 // add the invoice id
 SOAPElement invoiceIdElem = resultElem.addChildElement("invoiceId");
 long invoiceId = invoice.getInvoiceId();
 invoiceIdElem.addTextNode(String.valueOf(invoiceId));
Creating output (incomplete)
//add invoice items
 InvoiceItemBean items[] = invoice.getInvoiceItems();
 for (int i=0;i<items.length;i++) {
   SOAPElement invoiceItemElem =
         resultElem.addChildElement("invoiceItems");
   SOAPElement nameElem = invoiceItemElem.addChildElement("name");
   String name = items[i].getName();
   nameElem.addTextNode(name);
   SOAPElement perItemPriceElem =
        invoiceItemElem.addChildElement("perItemPrice");
   float perItemPrice = items[i].getPerItemPrice();
   perItemPriceElem.addTextNode(String.valueOf(perItemPrice));
   SOAPElement totalLineItemPriceElem =
      invoiceItemElem.addChildElement( "totalLineItemPrice");
   float totalLineItemPrice = items[i].getTotalLineItemPrice();
   totalLineItemPriceElem.addTextNode(
       String.valueOf(totalLineItemPrice));
   SOAPElement quantityElem =
       invoiceItemElem.addChildElement("quantity");
   int qty = items[i].getQuantity();
   quantityElem.addTextNode(String.valueOf(qty));
 }
Creating output (incomplete)
// save and return
  outputMessage.saveChanges();
  return outputMessage;
}
SAAJ Requestor

public static SOAPMessage createSOAPRequest(long
  invoiceId)
       throws SOAPException {
  // Create message factory
  MessageFactory messageFactory =
  MessageFactory.newInstance();
  // Create a message
  SOAPMessage message =
  messageFactory.createMessage();
  SOAPPart soapPart = message.getSOAPPart();
  SOAPEnvelope envelope = soapPart.getEnvelope();
SAAJ Requestor

// Get the SOAP header from the message and remove it
  SOAPHeader header = message.getSOAPHeader();
  header.detachNode();
  // Get the SOAP body from the message
  SOAPBody soapBody = message.getSOAPBody();
   // create the outer invoice element
  Name getInvoiceName =
         envelope.createName("getInvoiceById",
           null,
           "http://ibiblio.org/invoice/types");
  SOAPBodyElement getInvoiceElem =
          soapBody.addBodyElement(getInvoiceName);
SAAJ Requestor

 // create the invoice parameter
 Name invoiceIdName =
  envelope.createName("long_1",null,"");
 SOAPElement invoiceIdElem =
      getInvoiceElem.addChildElement(invoiceIdName);
 invoiceIdElem.addNamespaceDeclaration("","");
 invoiceIdElem.addTextNode(String.valueOf(invoiceId));
 message.saveChanges();

 return message;
   }
SAAJ Code Problems
   Compliant with SOAP…
   Still haven’t done anything with WSDL
   Lots and lots of XML creation and parsing
   Absolutely no error checking – not even
    simple type checking
   Have to handle all interoperability problems
JAX-RPC

  JAX-RPC Requestor Runtime                       JAX-RPC Provider Runtime



                Requestor                                            Provider
                Application   Generated           Servant           Application
                  Logic                                               Logic
                                Code             Service
                                                Endpoint
                                                Interface
                                   Generated
                                     Code




                  Stubs                           Ties



                HTTP Client      SOAP          HTTP Server
JAX-RPC Service Endpoint
Interface
package org.ibiblio.mdthomas.ws.autopartssupplier;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface InvoiceWebService extends Remote
  {

    public InvoiceBean getInvoiceById(long id)
      throws RemoteException;
}
JAX-RPC Servant
public class InvoiceHelper
  implements InvoiceWebService {

  // existing code

  }
Run the tools
   SEI-to-WSDL tool and WSDL-to-SEI tool are
    required by JAX-RPC specification
   Wscompile and wsdeploy with the Java Web
    Services Development Pack from Sun
   Java2WSDL with Apache Axis
Web Service “home page”
Web Service WSDL
JAX-RPC Requestor
public static void main(String[] args) {
        try {
         // Get the web service port
    InvoiceWebService_Service wsDef =
            new InvoiceWebService_Service_Impl();
        InvoiceWebService_PortType stub =
            wsDef.getInvoiceWebServicePort();

      // Create the input parameter
      GetInvoiceById idWrapper = new GetInvoiceById(1000);
      // Make the remote call to the web service
      GetInvoiceByIdResponse invoiceWrapper =
             stub.getInvoiceById(idWrapper);

      // Unwrap the result
      InvoiceBean invoice = invoiceWrapper.getResult();
      // Print some data
      CustomerBean customer = invoice.getCustomer();
      System.out.println("Customer: "+customer.getName());
      InvoiceItemBean items[] = invoice.getInvoiceItems();
      for (int i=0;i<items.length;i++) {
        System.out.println("item name: "+items[i].getName());
      }

       } catch (Exception ex) {
           ex.printStackTrace();
       }
  }
JAX-RPC Requestor
public static void main(String[] args) {
        try {
         // Get the web service port
    InvoiceWebService_Service wsDef =
            new InvoiceWebService_Service_Impl();
        InvoiceWebService_PortType stub =
            wsDef.getInvoiceWebServicePort();

    // Create the input parameter
    GetInvoiceById idWrapper = new GetInvoiceById(1000);
    // Make the remote call to the web service
    GetInvoiceByIdResponse invoiceWrapper =
            stub.getInvoiceById(idWrapper);

    // Unwrap the result
    InvoiceBean invoice = invoiceWrapper.getResult();
    // Print some data
    CustomerBean customer = invoice.getCustomer();
    System.out.println("Customer: "+customer.getName());
    InvoiceItemBean items[] = invoice.getInvoiceItems();
    for (int i=0;i<items.length;i++) {
      System.out.println("item name: "+items[i].getName());
    }

     } catch (Exception ex) {
         ex.printStackTrace();
     }
.NET C# Requestor
   Generate C# requestor based on WSDL:
>wsdl.exe /language:CS /protocol:SOAP \
http://localhost:8080/invoice/jaxrpc/invoice?WSDL


   Entry point:
public getInvoiceByIdResponse getInvoiceById(
     [System.Xml.Serialization.XmlElementAttribute("getInvoiceById",
     Namespace="http://www.ibiblio.org/mdthomas/invoice/types")]
  getInvoiceById getInvoiceById1) {
        object[] results = this.Invoke("getInvoiceById",
                 new object[] {getInvoiceById1});
        return ((getInvoiceByIdResponse)(results[0]));
    }
.NET C# Requestor
class JAXClient {

 [STAThread]
 static void Main(string[] args) {

    // Create the stub
    InvoiceWebService service = new InvoiceWebService();
    // Set the endpoint
    if (args.Length == 1)
       service.Url = args[0];
    else
      service.Url = "http://localhost:8080/invoice-jaxrpc/invoice";

    // create and send the request
    getInvoiceById idWrapper = new getInvoiceById();
    idWrapper.long_1 = 1000;
    getInvoiceByIdResponse responseWrapper = service.getInvoiceById(idWrapper);

    // Receive and process the result
    InvoiceBean invoice = responseWrapper.result;
    Console.WriteLine("Invoice id: "+invoice.invoiceId);
    CustomerBean customer = invoice.customer;
    Console.WriteLine("Customer: "+customer.name);

  for (int i=0;i<invoice.invoiceItems.Length;i++) {
     Console.WriteLine("item name: "+invoice.invoiceItems[i].name);
  }
 }
}
Web Services Architecture
   Web Services as a presentation layer
    technology
   Service Oriented Architecture (SOA) & Web
    Services
   Message Exchange Patterns (MEPs)
   RPC centric vs. Document centric
    approaches
   Relevant SOAP & WSDL details
Web Services And
Presentation Layer
Web Services And
Presentation Layer
Fallacies Of Distributed
Computing (Peter Deutch)
• The   network is reliable
• Latency is zero
• Bandwidth is infinite
• The network is secure
• Topology doesn’t change
• There is one administrator
• Transport cost is zero
• The network is homogeneous
Waldo On Distributed
Computing
“…work in distributed object-oriented systems
   that is based on a model that ignores or
   denies [the differences between local and
   remote objects] is doomed to failure, and
   could easily lead to an industry-wide rejection
   of the notion of distributed object-based
   systems."
-- Jim Waldo et al, “A Note on Distributed
   Computing,” 1994
Local objects are different than
remote objects
   Local objects are different than remote
    objects because:
       Different address spaces (by reference vs. by
        copy)
       Latency
       Partial failure
       Concurrency
Service Oriented Architecture
(SOA)
   Services have network interfaces
   Service providers and consumers are loosely
    coupled
   Interfaces are coarse grained
   Location is transparent
   Services can be looked up in a registry
   Consumer can bind to a provider at runtime
SOA applied to EJBs
   EJBs do distributed computing
   J2EE patterns that promote SOA tenets:
       Session Façade pattern with Value Objects for
        “bind” and “execute”
       Service Locator pattern for “find”
SOA Applied to EJBs
     HttpServlet




                                                               «uses»
PresentationProcessor        BusinessDelegate                                                    «JavaBean»
                                                                                                 ValueObject




                                                                                 «returns»


                                                               ServiceLocator




                                                                 «locates»
                                                «returns»



                                                                «SessionEJB»
                        SessionFacadeRemote      «proxy for»   SessionFacade                     «EntityEJB»
                                                                                «local access»   EntityBean




      Servlet Container JVM                                             EJB Container JVM
    SOA Applied To Web Services
WebServicesRequestor      UDDIProxy   WebServiceProvider      BusinessLogicObject


              Find WSDL




                       SOAP Request
                                                 Execute Business Logic
                                                                          Create
                                                                                   ProviderValueObject


                                                                  Read
            SOAP Response (Value Obj. as XML)

                                                Create
                                                                                              RequestorValueObject


                                                     Read
Message Exchange Patterns
   Message Exchange Patterns (MEPs): how
    messages are exchanged
   There are really two:
       Request-response
       One way
   WSDL defines two others, notification and
    solicit response, which aren’t supported by
    J2EE and aren’t widely used
   Code to MEPs, not to the underlying protocol
Request-response over HTTP
One way MEP over HTTP
Request-response MEP over
SMTP
RPC Centric vs. Document
Centric
   RPC Centric: Web services transmit objects
    as XML
   Document Centric: Web services transmit
    XML documents. Applications on either end
    create and parse XML documents
   RPC is more closely associated with the
    request-response MEP
   Document centric is more closely associated
    with the one way MEP
Document Centric Approach
RPC Centric Approach
RPC vs. Doc and J2EE
   JAX-RPC is an RPC centric approach
   JAXM is document centric
   SAAJ is low-level – document centric by default
   Document centric is best when you are really
    dealing with documents – newsfeeds for example
   Doesn’t make sense to change XML to objects
    back to XML again
   Usually, you want to deal with objects, not XML
   However:
       Business tends to think in documents (P.O., Invoice)
       Documents are more naturally coarse grained
WSDL & SOAP
   SOAP wire-line protocol
   SOAP envelope, body and headers:
       Body: Just transporting the data
       Header: Meta-data. Higher standards use headers
       Envelope: just a container
   WSDL describes the web service
   Similar to Java method signatures
   WSDL is very interesting
   Helps to understand WSDL to do JAX-RPC
   Can go a long way with JAX-RPC without knowing
    anything about SOAP
WSDL compared to Java
   WSDL Type
                   WSDL Message
   (Java Value
                  (Java Parameter)
   Object Type)

                     WSDL Operation
                      (Java Method)


   WSDL Type
                   WSDL Message
   (Java Value
                  (Java Parameter)
   Object Type)

                     WSDL Operation
                      (Java Method)
                                      WSDL Port Type
                                      (Java Interface)
WSDL
   Service                    Operation                        Message


                                            1            *

   1                                *                                *

                                    1

                              PortType

                                                                         1        Type               «uses»     XSD Type


                               1

   *                           *
                                                                                       «specifies»              Style
       Port                   Binding           «uses»       SOAP:Binding
                                                                                 «specifies»
                  1   1
                                                                             1
              *
                                                                                   *
              1

SOAP:Address      1       1         URI                                          Encoding




                                          Literal XML              SOAP Section 5 Encoding             Document Style      RPC Style
Interoperability Challenges
 Interoperability is the chief challenge of web
  services
 Tools generating SOAP, WSDL, UDDI, etc. need
  to be interoperable
 A more complex variation of the “Browser Wars” of
  the 1990’s
 Web Services Interoperability (WS-I) dedicated to
  Interoperability
 WS-I Basic Profile 1.0 declares an interoperable
  web services platform
WS-I Basic Profile
 WS-I   Basic Profile 1.0:
  SOAP 1.1
  WSDL 1.1

  Must use HTTP binding, should use HTTP 1.1

  XML Schema Part 1, Part 2

  May use HTTPS

  SOAP messages should use document/literal

 Similar   to the J2EE certification program
 JAX-RPC
   selling point: Never have to program against
• Big
SOAP
• Big value add: Generated code (not the APIs)
• Addresses interoperability problems because the
code generators can adhere to WS-I Basic Profile
1.0
• Uses Façade and Value Object patterns
• RPC-centric, though you can start with defined
WSDL and XSD
• Tends to use request-response MEP, but can
work with one-way MEP
JAX-RPC

                                            JAX-RPC Provider Runtime
 JAX-RPC Requestor Runtime


              Requestor                                        Provider
              Application                    Servant          Application
                Logic                                           Logic
                                            Service
                  Service                  Endpoint
                 Endpoint                  Interface
                 Interface


             Message Handlers          Message Handlers


 Custom                                                       Custom
  Type            Stubs                      Ties              Type
 Handlers                                                     Handlers


               HTTP Client      SOAP     HTTP Server
JAX-RPC Interoperability

 JAX-RPC                   JAX-RPC
 Requestor                 Provider




Non JAX-RPC            Non JAX-RPC
 Requestor               Provider
JAX-RPC SEI-first Provider
Development
Service Endpoint Interface first – web services
   enabling existing Java code
1. Define a Service Endpoint Interface

2. Implement the Servant – ties to business
   logic
3. Generate WSDL with JAX-RPC

4. Create WAR

5. Deploy to servlet container
   JAX-RPC SEI-first Provider
   Development
<?xml version="1.0" encoding="UTF-8"?>
<configuration
  xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
 <service name="InvoiceWebService"
   targetNamespace="http://www.ibiblio.org/mdthomas/invoice"
   typeNamespace="http://www.ibiblio.org/mdthomas/invoice/types"
   packageName="org.ibiblio.mdthomas.ws.autopartssupplier">
  <interface
   name="org.ibiblio.mdthomas.ws.autopartssupplier.InvoiceWebService"/>
 </service>
</configuration>
 JAX-RPC Requestor
 Development
1.   Point at the WSDL file
2.   Generate stubs
3.   Code against the stubs
    Stubs mirror the WSDL entities
    The SEI is generated for the requestor side
    Value objects are generated
    SEI and value objects are usually in a different
     package
    Can generate a JAX-RPC Requestor against
     non JAX-RPC generated WSDL documents
JAX-RPC Requestor
Development
<?xml version="1.0" encoding="UTF-8"?>
<configuration
 xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
 <wsdl location="InvoiceWebService.wsdl"
       packageName="invoicestub"/>
</configuration>
JAX-RPC WSDL-first
Development
1.   Point to the WSDL
2.   Generate SEI, value objects
3.   Code Servant
4.   Generate Ties
5.   Create WAR
6.   Deploy to servlet container
WSDL generated Java
   WSDL supersets Java in several areas
   Can define multiple OUT and IN/OUT parameters
   JAX-RPC uses holder objects for these
   Can define one-way operations
   WSDL can do stronger typing than Java (e.g.,
    regular expression facets)
   Headers can be mapped as “explicit context” to an
    SEI call – a header will be passed to the SEI
    method as a parameter
Service Endpoint Interfaces
(SEIs)
1.   Must extend java.rmi.Remote
2.   Every method must throw RemoteException
3.   No constant declarations
4.   Parameters and return types must be valid
     JAX-RPC types
    #4 is the big one
JAX-RPC Types
   XML (and thus web services) is data-centric not
    object-centric
   Valid JAX-RPC types are what could be
    considered “value types”
   Java primitives and primitive wrappers (int,
    Integer, long, Long, etc.)
   Some standard Java classes (e.g., String, Date)
   Java value types (method-less Java classes or,
    roughly, JavaBeans)
   Arrays
JAX-RPC Standard Types
   java.lang.String
   java.math.BigInteger
   java.math.BigDecimal
   java.util.Calendar
   java.util.Date
   java.xml.namespace.QName
   java.net.URI
Value Object Types
   Default no object constructor
   Must not implement Remote
   Methods are not mapped to the transmitted
    XML
   Java Bean properties and public, non-final,
    non-static fields are mapped
   Fields/properties can be any valid JAX-RPC
    type
Value Object
public class PersonValueType {
    public String name;
    public Date birthDate;
    public boolean smoker;
    public String sex;
    public int cholestrolLevel;
    public URI webSite;
    public PersonValueType mom;
    public PersonValueType dad;
    public PersonValueType children[];
}
Exceptions & SOAP Faults
   Can declare exceptions in an SEI
   Will declare an equivalent fault in the WSDL
    file
   Exception will be thrown on the requestor
    when a fault is received
   Exceptions in the SEI must not extend
    RuntimeException
JAX-RPC Polymorphism
   Subtypes of a declared return type can be
    returned
   Must tell the code generation tool about the
    sub-types if they don’t appear elsewhere in
    the SEI
   WSDL supports extensible types
   Can downcast in the JAX-RPC requestor
    code
Handlers
   JAX-RPC message handlers give you a way
    to access a SOAP message before or after
    its ultimate processing
   Handler interface has three methods:
       handleRequest
       handleResponse
       handleFault
 JAX-RPC Handlers



            Handler             Handler
Requestor      1                   2
                      Network             Servant
  App.
            Handler             Handler
               4                   3
ServletEndpointInterface
   ServletEndpointInterface provides access to the
    underlying servlet context
   Can use it inside a JAX-RPC servant to:
       Get/set values to an HTTPSession
       Interface with HTTP authentication
       Get resources
   Be careful:
       SOAP is designed to be transport (i.e., HTTP)
        independent (but WS-I says its okay to use HTTP
        cookies)
       The requestor must support cookies and behave
        correctly! (Not the same as assuming a web browser
        will behave correctly)
ServletEndpointContext
public class HttpAccessServant implements HttpAccess, ServiceLifecycle
   {

    ServletEndpointContext context;

    public void init(Object o) {
      context = (ServletEndpointContext)o;
    }

    public void destroy() {
    }

    public void setHttpSessionAttribute(String key, String val)
        throws RemoteException {
       HttpSession session = context.getHttpSession();
       session.setAttribute(key,val);
    }
}
2.1 Stateless Session Beans
and Web Services
   EJB 2.1 specifies that Stateless Session
    Beans may declare a SEI
   Similar to a remote component interface
   EJB container is a JAX-RPC runtime –
    manages requests to the SEI
   One step simpler than a servlet based SEI
    that accesses the Stateless Session Bean
    through a Session Façade pattern
Differences Between Servlet JAX-
RPC & EJB Container JAX-RPC
   Different network architecture: May not want
    outside HTTP connections to the EJB
    Container
   Differences in transport implementation
   EJB 2.1 does not require that the EJB
    container support HTTP sessions
Static vs. Dynamic Requestors
   Static proxy: Use stubs generated by WSDL-to-
    Java tool at compile time
   Dynamic proxy: Use proxy created at runtime,
    though SEI is generated at compile time
   Dynamic Invocation Interface (DII): Completely
    dynamic. Signature of web service and WSDL
    doesn’t need to be known until runtime
   Requestors and providers are usually
    somewhat coupled at compile time, even if you
    use DII
Apache Axis
   Axis is a web services engine
   Implements JAX-RPC 1.1, SAAJ 1.2
    specification
   Axis details beyond J2EE standards:
       JWS deployment – similar to JSP
       WSDD for deploying web services
   Currently, some weaknesses in supporting
    WS-I Basic Profile (e.g., document/literal)
   Should be addressed soon
SAAJ
   SAAJ is a wrapper for XML parsing and can
    handle HTTP calls
   SAAJ provides convenience methods for
    accessing the SOAP envelope, headers and
    body
   Similar to JDOM
   Can bridge to W3C DOM APIs
JAXM & Messaging
   JAXM is an asynchronous, queue-based
    messaging API
   Not part of J2EE 1.4
   Uses queues on either side
   Doesn’t provide WSDL facilities
   Can be used in conjunction with JAXB to
    convert to objects
JAXR
   JAXR – API for XML registries
   Generic: Can be used with any XML registry
   Support for UDDI and ebXML
   Has support for querying and for publishing
   Publishing requires authentication
   Can set up your own “private” UDDI registries
    that act as a naming service
Conclusions
   JAX-RPC: quickest solution for synchronous, RPC
    style web services and for service-enabling
    existing code
   RPC model isn’t always best – if it’s too fine
    grained it violates SOA
   SOA – coarse grained, loosely coupled interfaces
   JAXP – Avoid if possible. Use JAXB/Castor to
    translate into an object model
   JAXM – Good for message style services
   SOAP & WSDL – WSDL is more interesting
   JAXR – Used for access to XML Registries (i.e.,
    UDDI)

								
To top