Soap and web service

fault

  • The receiver is required to send a SOAP fault back to the immediate sender only if the Request/Response messaging mode is used
  • you don't send the fault to the original sender unless it's also the immediate sender. When that sender receives the fault message, it may take some action, such as undoing operations, and may send another fault further upstream to the next sender if there is one.
  • the Body of the SOAP message must contain only a single Fault element and nothing else.
  • The Fault element itself must contain a faultcode element and a faultstring element, and optionally faultactor and detail elements.

message

A message part may declare either a type attribute or an element attribute, but not both. Which to use depends on the kind of messaging you're doing. If you're using RPC-style messaging, the part elements must use the type attribute; if you're using document-style messaging, the part elements must use the element attribute

very good post about RPC vs Document. encoded vs literal
http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/

portType

  • In addition to input and output messages an operation may include zero or more fault messages, each of which describes a different kind of error.
  • The Basic Profile fixes these by providing a single interpretation of the parameterOrder attribute. The order of parameters transmitted from sender to receiver must follow the order of part declarations made in input and output message definitions.
  • the Basic Profile prohibits operation overloading

binding

  • the Basic Profile requires that style attributes declared by soapbind:operation elements have the same value as the style attribute of their soapbind:binding element
  • the binding attribute: type maps to portType name; operation attribute : name maps to portType operation name;
  • If this attribute : soapAction is omitted or empty, then the SOAPAction HTTP header field must be present and must contain an empty string
  • The style of messaging has a direct impact on how the body of the SOAP message is constructed. When you use RPC-style messaging, the Body of the SOAP message will contain an element that represents the operation to be performed.(operation name). When you use document-style messaging, the XML document fragment will be the direct child of the Body element of the SOAP message.(the input/out message name) The operation is not identified.
  • in soapbind:body, In "rpc"-style messages, the namespace attribute must be specified with a valid namespace that can be the same as the targetNamespace of the WSDL document. In contrast, document-style messages must not specify the namespace attribute in the soapbind:body element. The namespace of the XML document fragment is derived from its XML schema

why the operation name is not namespace qualified.

http://www2.roguewave.com/support/docs/leif/leif/html/leifug/B-6.html

B.6 binding Element

A binding element describes a specific communication protocol for a portType element. Each binding corresponds to a portType in the WSDL document. The binding element describes the specific protocol for each message in each operation of the portType element. A binding element may contain extension elements that provide information for the specific binding. The sample below shows the basic outline of a binding for a SOAP message:

<binding name="BindingName" type="PortTypeRef">
        <soap:binding style="rpc|document"
          transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="OperationName">
          <soap:operation soapAction="ActionValue"/>
          <input>
            <soap:body
              encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
              namespace="TargetNamespace"
              use="encoded"/>
         </input>
         <output>
          <soap:body
            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            namespace="TargetNamespace"
            use="encoded"/>
         </output>
        </operation>
      </binding>

The BindingName sets the name of the binding. The PortTypeRef refers to a portType defined elsewhere in the WSDL document. The PortTypeRef must be namespace qualified if the targetNamespace for the WSDL definitions element is not the same as the default namespace. The TargetNamespace is the targetNamespace for the WSDL document, or the default namespace for the document if no targetNamespace is set.

The OperationName sets the name of the operation this binding applies to. This name must match the name of an operation declared within the portType referenced in PortTypeRef. However, the OperationName is a declaration, not a reference, so the name need not be namespace qualified.

The sample below shows the binding defined in WeatherSummary.wsdl:

<binding name="WeatherSummary" type="tns:WeatherSummary">
 
        <soap:binding style="rpc"
           transport="http://schemas.xmlsoap.org/soap/http"/>
 
        <operation name="getSummary">
          <soap:operation soapAction="getSummary"/>
          <input>
            <soap:body
              encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
              namespace="http://www.roguewave.com/webservices/examples"
              use="encoded"/>
          </input>
          <output>
            <soap:body
              encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
              namespace="http://www.roguewave.com/webservices/examples"
              use="encoded"/>
          </output>
        </operation>
      </binding>

The type attribute of the binding element specifies that the element is a binding for the portType named WeatherSummary. Each level of the binding contains an element from the soap namespace. These elements define the binding from the parts in the portType to the parts of a SOAP message.

Each soap element provides information about the WSDL element that contains the soap element. The soap:binding element states that the operations in this binding use RPC-style SOAP transmitted via HTTP. The soap:operation element states that HTTP requests to the operation named getSummary must include a SoapAction HTTP header with the value getSummary. The soap:body elements state that the input and output messages defined in the portType form the contents of the body of a SOAP message.

The binding describes the specific format and transport protocol for each message. The binding does not, however, define a network address for the messages.

FTP binding

https://open-esb.dev.java.net/kb/beta2/60/ep-ftp-bc.html

<binding name="binding1" type="tns:FTPPortType">
    <ftp:binding/>
    <operation name="FTPOperation">
        <ftp:operation/>
        <input name="input1">
            <ftp:message <!-- message transfer spec in IN-ROUTE -->
                   messageRepository="SYNC_REQ_RESP"
                   messageName="%u"
                   messageNamePrefixIB="req."
                   messageNamePrefixOB="resp."
                   archive="true"
                   protect="true"
                   stage="true"
                   use="literal"
                   part=""
                   encodingStyle=""
                   messageCorrelate="true"
                   pollIntervalMillis="5000"/>
        </input>
        <output name="output1">
            <ftp:message <!--  message transfer spec in OUT-ROUTE -->
                   messageRepository="SYNC_REQ_RESP"
                   messageName="%u"
                   messageNamePrefixIB="req."
                   messageNamePrefixOB="resp."
                   archive="true"
                   protect="true"
                   stage="true"
                   use="literal"
                   part=""
                   encodingStyle=""
                   messageCorrelate="true"
                   pollIntervalMillis="5000"/>
        </output>
    </operation>
</binding>
 
<wsdl:service name="FTPService">
    <wsdl:port name="FTPServicePort"  binding="tns:binding1">
        <ftp:address  location="ftp://example.com:1027/FTPServiceMain" />
    </wsdl:port>
</wsdl:service>

service

http://www2.roguewave.com/support/docs/leif/leif/html/leifug/B-7.html

B.7 service Element

A service element describes a Web service as a collection of port elements. A port element defines a specific network address for a binding. The sample below shows the basic outline of a service that supplies an address for a SOAP binding:

<service name="ServiceName">
        <port name="PortName" binding="BindingRef">
          <soap:address location="URL"/>
       </port>
      </service>

The ServiceName sets the name of the service. The PortName sets the name of the specific address. The BindingRef refers to the name of a binding element. The BindingRef must be namespace qualified if the targetNamespace for the WSDL definitions element is not the same as the default namespace.

The sample below shows the service defined in WeatherSummary.wsdl:

<service name="WeatherSummary">
        <documentation>WeatherSummary</documentation>
        <port binding="tns:WeatherSummary" name="WeatherSummary">
          <soap:address
            location="http://localhost:8090/weather/WeatherSummary"/>
        </port>
      </service>

The binding attribute of the port element specifies that the element is a port for the binding named WeatherSummary. The soap:address element within the port states that the port receives SOAP messages directed to the URL http://localhost:8090/weather/WeatherSummary/.

At this point, the Web service is completely defined.

xml schema

qualified

  • Global elements and attributes must always be qualified, which means that in an XML instance you must prefix them to form a QName. The exception is when a global element is a member of the default namespace, in which case it does not have to be qualified with a prefix—all unqualified elements are assumed to be part of the default namespace. The default namespace does not apply to global attributes; global attributes must always be prefixed.
  • schema defines two attributes, elementsForm Default and attributesFormDefault, that determine whether local elements in an XML instance need to be qualified with a prefix of targetNamespace or not. The default value of the fromElementDefault and the attributeElementDefault attributes is "unqualified"
  • If the XML document declares a default namespace, then all elements without prefixes are assigned to that namespace and are effectively qualified.
  • BEST PRACTICE. You are free to configure your schemas any way you want, but it's generally less confusing if you require that all elements be namespace-qualified by setting elementFormDefault equal to "qualified"

http://www.ibm.com/developerworks/webservices/library/ws-tip-namespace.html#listing8

global attributes

http://www.datypic.com/books/defxmlschema/chapter08.html

nice examples

soap client with Apache CXF
http://logicsector.wordpress.com/2008/10/19/how-to-create-a-wsdl-first-soap-client-in-java-with-cxf-and-maven/

URI, URL, URN

* the set of URNs of the form "urn:isbn:n-nn-nnnnnn-n" is a URN namespace.
* A Universal Resource Identifier (URI) is a generic representation that can either be a Universal Resource Locator (URL) or a Universal Resource Name (URN). A URL is
something that represents a physical network location and contains things that pertain to a particular protocal, such as http:// or ftp://. A URN is something that does not necessarily resolve to any physical location; generally, it is intended to be used to identify something uniquely, such as a SOAP action or a namespace.

toolkits

A number of toolkits may be used to develop web services in the Java programming language.

  • One such toolkit is the very popular open source implementation of SOAP called Apache AXIS. AXIS is from the Apache Software Foundation (http://ws.apache.org/axis), an organization that provides support for open source projects.
  • Another such toolkit is the Java API for XML-based Web Services (JAX-WS), which provides a Java API for developing and implementing web services. JAX-WS handles all the details of the SOAP layer, enabling development in terms of simple method calls. JAX-WS is available in an early release reference implementation from https://jax-rpc.dev.java.net. the predecessor of JAX-WS is JAX-RPC
  • Apache CXF (new XFire)

JAX-RPC vs JAXM

The Java API for XML Messaging (JAXM) and the Java API for XML-based RPC (JAX-RPC) are both part of the Java Web Services Developer Pack.

The real distinction between JAXM and JAX-RPC is that JAXM forces the developer to work directly with the SOAP envelope constructs, and
JAX-RPC provides a high-level, WSDL-based framework that hides details of the SOAP envelope from the developer. JAX-RPC uses WSDL to generate your messages and provides an object-oriented (i.e., RMI-like) interface to the developer. JAXM doesn't use WSDL, so the developer must construct messages by hand and send or process them explicitly.

JAXM consists of two main areas. The "messaging" capability provides a pattern for sending and receiving SOAP messages, with or without attachments. The SOAP packaging part provides APIs for constructing and deconstructing SOAP and MIME envelopes. Generally, the functionality is separated cleanly between the javax.xml.messaging package and javax.xml.soap packages(which is shared by both JAXM and JAX-RPC. )

JAX-WS

A Java application can use the API defined in SOAP with Attachments API for Java (SAAJ) to create, send, and receive SOAP messages. This API is contained in the javax.xml.soap package, which is included in the Java EE 5 SDK
JAX-WS uses the SAAJ API under the covers to produce and consume the SOAP message

is the Remote the same as @Remote in J2EE1.5 annotation?
package webservices;
import java.rmi.Remote;
 
public interface SimpleService extends Remote
{
String echo(String input);
}

The Remote interface SimpleService extends is not the familiar javax.ejb.Remote annotation used with session beans. This particular Remote interface, java.rmi.Remote, isused by JAX-WS to generate the appropriate implementation code when a client requests an instance of the interface to invoke methods on the server.

JAX-WS and JAXB

JAX-WS becomes more widely implemented, the options available to developers in terms of WSDL binding will increase. JAX-WS will work in concert
with Java API for XML Binding (JAXB) 2.0 to provide a richer, less limited model. so you don't need adhering purely to primitive types

UDDI/JAXR

There is also an API known as Java API for XML Registries (JAXR) that provides a uniform interface to registries such as UDDI.

SOAP Client Invocation Model

JAX-RPC defines three different client models used to invoke a remote method: one static model and two dynamic models.

  • The statically defined stub model is typically based on a code generation tool.
  • The dynamic model doesn't need code generation tool.
    • The dynamic proxy invocation model is based on building a proxy object dynamically using the reflection APIs (java.lang.reflect).
    • The Dynamic Invocation Interface (DII) is based on a Call object;

Statically Generated Stubs

A tool can generate a class that implements the javax.xml.rpc.stub interface, which contains the following methods:

package javax.xml.rpc; 
public interface Stub { 
    public void _setProperty(String name, Object value); 
    public Object _getProperty(String name); 
    public java.util.Iterator _getPropertyNames(  ); 
}

In addition to implementing these methods, the generated stub would have a method that matches the name of the actual service method, such as getLastTradePrice( ).

Dynamic Invocation Using the Service Interface

The javax.xml.rpc.Service interface encapsulates two flavors of dynamic invocation that do not require any generated code. These methods are :

  • dynamic proxy invocation via the getPort( ) method;
  • the DII using the Call interface
package javax.xml.rpc; 
public interface Service { 
 
    public Call createCall(  )  
            throws JAXRPCException; 
    public Call createCall(QName portName)  
            throws JAXRPCException; 
    public Call createCall(QName portName, java.lang.String operationName)  
            throws JAXRPCException; 
 
    public java.rmi.Remote getPort(QName portName,  
                                       java.lang.Class serviceDefInterface) 
            throws JAXRPCException; 
    public java.util.Iterator getPorts(  ); 
 
    public Qname getServiceName(  ); 
    public TypeMappingRegistry getTypeMappingRegistry(  ) 
            throws JAXRPCException; 
    public java.net.URL getWSDLDocumentLocation(  ); 
    public void setTypeMappingRegistry(TypeMappingRegistry registry) 
            throws JAXRPCException; 
}
Dynamic Proxy
com.example.StockQuoteProvider sqp = 
    (com.example.StockQuoteProvider)service.getPort(portName,  
        StockQuoteProvider.class); 
 
float price = sqp.getLastTradePrice("ACME");
Dynamic Invocation Interface (DII)

DII is based on a Call object. To get a Call object, use the javax.xml.rpc.Service.createCall( ) method.
then call addParameter(…) to build the method signature and call invoke(…)

AXIS1

*[ very nice tutorial]
* [ good tutorial]

AXIS2

Shared on both client and server (Classes for Serialization/Deserialization)

ComplexType

For each complex type defined, two encoding classes are generated: one defining a basic Java implementation of the structure defined by the complex type
(AvailabilityType.java in our case) and A holder if this type is used as an inout/out parameter (AvailabilityTypeHolder.java in our case).

Another file was generated for the xyzType complex type: XyzTypeHolder.java. This file is used to implement the behavior of in/out and multiple out parameters in an RPC-style Web service. please note, if only one out parameter, holder type won't be used, though it is still generated.

a good example of multiple outs and in/out

client

For the client, Axis generates three files:

  • An interface definition for each portType element (• PriceCheckPortType.java in our case)
  • A client-side stub class for each binding element (• PriceCheckSOAPBindingStub.java in our case) , which extends org.apache.axis.wsdl.Stub and implements the portType interface;
  • An interface for each service (• PriceCheckService.java in our case)
  • A service (locator) class, which implements this interface of service;
the routing

1)from service routed to Stub

package ch6.ex1;
 
public interface PriceCheckService extends javax.xml.rpc.Service {
 
  public PriceCheckPortType getPriceCheck()  throws javax.xml.rpc.ServiceException;
 
  public PriceCheckPortType getPriceCheck(java.net.URL portAddress) throws javax.xml.rpc.ServiceException
 
}
 
package ch6.ex1;
public class PriceCheckServiceLocator extends org.apache.axis.client.Service  implements PriceCheckService {
 
    // Use to get a proxy class for PriceCheck
    private final java.lang.String PriceCheck_address = "http://localhost:8080/axis/services/PriceCheck";
 
    public PriceCheckPortType getPriceCheck() throws javax.xml.rpc.ServiceException {
        java.net.URL endpoint;
        try {
                endpoint = new java.net.URL(PriceCheck_address);
        }
        catch (java.net.MalformedURLException e) {
                return null; // unlikely as URL was validated in wsdl2java
        }
        return getPriceCheck(endpoint);
    }
 
    public PriceCheckPortType getPriceCheck(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
        try {
                return new PriceCheckSOAPBindingStub(portAddress);     //<-----------
        }
        catch (org.apache.axis.SerializationException e) {
                return null; // ???
        }
    }
}

2) Stub does all the dirty job.

package ch6.ex1;
public class PriceCheckSOAPBindingStub extends org.apache.axis.wsdl.Stub  implements PriceCheckPortType{
 
    ...
 
    public AvailabilityType checkPrice(String sku) throws java.rmi.RemoteException{
        if (call.get(org.apache.axis.transport.http.HTTPTransport.URL) == null){
                throw new org.apache.axis.NoEndPointException();
        }
 
        call.set(org.apache.axis.transport.http.HTTPTransport.ACTION, "");
        Object resp = call.invoke("http://www.skatestown.com/services/PriceCheck", "checkPrice", new Object[]
                {new org.apache.axis.message.RPCParam("sku", sku)} );
 
        if (resp instanceof java.rmi.RemoteException) {
                throw (java.rmi.RemoteException)resp;
        }
        else {
                return (AvailabilityType) resp;
        }
    }
}

server

For the server, Axis generates three files:

  • A server-side skeleton class based on each binding element (• PriceCheckSOAPBindingSkeleton.java in our case)
  • A server-side "empty" service implementation class file for each binding element (• PriceCheckSOAPBindingImpl.java in our case), which implements the portType interface
  • A modified interface file for each portType, specific for use by the Axis engine (• PriceCheckPortTypeAxis.java in our case). NOTE: The server-side interface is generated only if the —messageContext option is used.
the routing

1)In order for the Axis engine to know about a service, the service needs to be deployed. The current mechanism of deploying services in Axis is through a deployment descriptor in Web Service Deployment Descriptor (WSDD) format, which associate the particular service with an skeleton class.

deploy.wsdd:

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <service name="PriceCheck" provider="java:RPC">
    <parameter name="className" value="ch6.ex1.PriceCheckSOAPBindingSkeleton"/>
    <parameter name="allowedMethods" value="*"/>
  </service>
 
  <beanMapping qname="avail:AvailabilityType" xmlns:avail="http://www.skatestown.com/ns/availability"
               languageSpecificType="java:ch6.ex1.AvailabilityType"/>
 
</deployment>

2) the skeleton class calls the impl class

public class PriceCheckSOAPBindingSkeleton{
    private PriceCheckPortType impl;
 
    public PriceCheckSOAPBindingSkeleton() {
        this.impl = new PriceCheckSOAPBindingImpl();
    }
     ...
 
    public Object checkPrice(org.apache.axis.MessageContext ctx, String sku)  throws java.rmi.RemoteException
    {
        Object ret = impl.checkPrice(ctx, sku);
        return ret;
    }
}

RESTful Web services

  • RESTful Web services: The basics

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

  • An Introduction to Creating RESTful Web Services Using Jersey and Java

http://www.brucephillips.name/blog/index.cfm/2009/5/28/An-Introduction-to-Creating-RESTful-Web-Services-Using-Jersey-and-Java

  • RESTful via axis

http://wso2.org/library/3726

  • great tutorial

* part 1 : It's about the information, stupid
* part 2 : Restlet for the weary
* part 3 : NetKernel
* part 4 : The future is RESTful

Document vs RPC

http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License