Using xsd:any to Represent XML Documents in a Service Interface:
Design Details
The strategy for using xsd:any as the document type when
designing a document centric interface and endpoint is illustrated
by the document oriented applications available under the bpcatalog project hosted at java.net. This application has a
service endpoint designed to use xsd:any as the document type. The XML
document is represented by a purchase order sent by the client.
The application consists of these major entities:
- WSDL File: This is the description of the service interface that
accepts an XML document as xsd:any.
- AnyPurchaseOrderServiceSEI.java: This is the service endpoint
interface.
- AnyPurchaseOrderServiceImpl.java: This is the endpoint
implementation of the interface.
- Some deployment descriptors.
The WSDL File for the Service
The WSDL file in Code Example 1 describes
the web service. The development style we chose was to start with WSDL
and generate the necessary Java[TM] classes from it. So choosing the
proper types for the message parts in the WSDL is very important, since
these types in the WSDL file will result in the types of the parameters
in the generated Java code. Note that the <any/>
type is specified for the document sent as a parameter to the submitPO
method as well as for the return value. Also note an application defined
service exception declared in the WSDL.
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:AnyPurchaseOrderService">
<complexType name="submitPO">
<sequence>
<any/>
</sequence>
</complexType>
<complexType name="submitPOResponse">
<sequence>
<any/>
</sequence>
</complexType>
<complexType
name="InvalidPOException">
<sequence>
<element name="message" type="string"
nillable="true"/>
</sequence>
</complexType>
<element name="submitPO" type="tns:submitPO"/>
<element name="submitPOResponse"
type="tns:submitPOResponse"/>
<element name="InvalidPOException"
type="tns:InvalidPOException"/>
</schema>
</types>
<message name="AnyPurchaseOrderServiceSEI_submitPO">
<part name="parameters"
element="tns:submitPO"/>
</message>
<message name="AnyPurchaseOrderServiceSEI_submitPOResponse">
<part name="result"
element="tns:submitPOResponse"/>
</message>
<message name="InvalidPOException">
<part name="InvalidPOException"
element="tns:InvalidPOException"/>
</message>
<portType name="AnyPurchaseOrderServiceSEI">
<operation name="submitPO">
<input
message="tns:AnyPurchaseOrderServiceSEI_submitPO"/>
<output
message="tns:AnyPurchaseOrderServiceSEI_submitPOResponse"/>
<fault name="InvalidPOException"
message="tns:InvalidPOException"/>
</operation>
</portType>
Code Example 1: Snippet of the WSDL for the Service
The Service Endpoint Interface
Since we start with the WSDL, the service endpoint interface in Code Example 2 gets generated based on the
information contained in the WSDL. The service endpoint interface has a submitPO()
method that accepts a SubmitPO
object. The class SubmitPO
corresponds to the complex type containing xsd:any defined in the
WSDL and is a JavaBeans[TM] component that is basically just a wrapper
class containing a javax.xml.soap.SOAPElement representation of the XML
purchase order document. Note that the response type was
specified using xsd:any so the XML document returned also has a wrapper
JavaBeans class called SubmitPOResponse
containing
the purchase order XML document as a SOAPELement. The
application-defined exception InvalidPOException
is also
generated from the WSDL.
public interface
AnyPurchaseOrderServiceSEI extends Remote {
public SubmitPOResponse submitPO(SubmitPO
parameters) throws
InvalidPOException,
RemoteException;
}
Code Example 2: The service endpoint interface
Code Example 3 shows the SubmitPO
class that gets generated from the WSDL. This JavaBean wrapper class
contains the purchase order XML document as a SOAPElement.
public class SubmitPO {
protected javax.xml.soap.SOAPElement _any;
public SubmitPO() {
}
public SubmitPO(javax.xml.soap.SOAPElement _any) {
this._any = _any;
}
public javax.xml.soap.SOAPElement get_any() {
return _any;
}
public void set_any(javax.xml.soap.SOAPElement _any) {
this._any = _any;
}
}
Code Example 3: The SubmitPO Wrapper Class
Containing the Purchase Order XML Document as a SOAP Element That Is
Generated From the WSDL
The Java Endpoint Implementation
For this application we chose to use a web component to implement the
service interface. Code Example 4
shows the endpoint implementation class. We could instead have used an
Enterprise JavaBeans[TM] (EJB[TM]) component to implement the endpoint.
Either choice would work. An important point to notice is that the
purchase order XML is handled as a SOAPElement and is used after
calling a get method on the SubmoitPO wrapper class shown in Code Example 3.
public class
AnyPurchaseOrderServiceImpl implements
AnyPurchaseOrderServiceSEI,
ServiceLifecycle {
private ServletEndpointContext context;
private POXMLUtil xmlUtil;
public void init(Object context) {
this.context =
(ServletEndpointContext) context;
xmlUtil = new POXMLUtil();
}
public void destroy() {}
public SubmitPOResponse submitPO(SubmitPO request)
throws InvalidPOException, RemoteException {
String id = null;
SubmitPOResponse reply =
null;
try{
SOAPElement requestdata= request.get_any();
//extract the PO ID
NodeList list =
((Element)requestdata).getElementsByTagNameNS("urn:AnyTypePurchaseOrderService",
"poId");
for
(int loop = 0; loop < list.getLength(); loop++) {
Node node = list.item(loop);
if (node != null) {
Node child = node.getFirstChild();
if ((child != null) && child.getNodeValue() != null){
id = child.getNodeValue();
}
}
}
SOAPElement replydata = xmlUtil.createSOAPMessage(id);
reply = new SubmitPOResponse();
reply.set_any(replydata);
} catch(Exception exe){
throw new RuntimeException("AnyPOService Having
Problems:"+exe.getMessage(), exe);
}
//this is done just to
illustrate throwing an application specific exception
if(id.equals("100"))
throw new InvalidPOException("Invalid ID for the purchase order!!! " +
"For demo purposes, we throw " +
"an application defined exception for the ID value of 100.");
return reply;
}
}
Code Example 4: The Endpoint Implementation
The Deployment Descriptors
A web service in Java[TM] 2 Platform, Enterprise Edition (J2EE[TM]
platform) is packaged into a deployment module such as a war or an ear
file. In this application, we packaged it as a war file. The portable
packaging of a web service endpoint requires several deployment
descriptors as well as the Java classes. Here are some snippets from
the endpoint deployment descriptors:
<servlet>
<description>Endpoint for AnyPO Web
Service</description>
<display-name>AnyPurchaseOrderServiceImpl</display-name>
<servlet-name>AnyPurchaseOrderServiceImpl</servlet-name>
<servlet-class>com.sun.j2ee.blueprints.anyposervice.AnyPurchaseOrderServiceImpl</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
Code Example 5: Snippet From web.xml Deployment Descriptor
The endpoint also needs a web services deployment descriptor file,
webservices.xml, as shown below:
<webservice-description>
<webservice-description-name>AnyPurchaseOrderService</webservice-description-name>
<wsdl-file>WEB-INF/wsdl/AnyPurchaseOrderService.wsdl</wsdl-file>
<jaxrpc-mapping-file>WEB-INF/anypurchaseorderservice-mapping.xml</jaxrpc-mapping-file>
<port-component>
<description>port component
description</description>
<port-component-name>AnyPurchaseOrderService</port-component-name>
<wsdl-port
xmlns:anypons="urn:AnyPurchaseOrderService">anypons:AnyPurchaseOrderServiceSEIPort
</wsdl-port>
<service-endpoint-interface>com.sun.j2ee.blueprints.anyposervice.AnyPurchaseOrderServiceSEI
</service-endpoint-interface>
<service-impl-bean>
<servlet-link>AnyPurchaseOrderServiceImpl</servlet-link>
</service-impl-bean>
</port-component>
</webservice-description>
Code Example 6: Snippet From webservice.xml Deployment
Descriptor
The web services deployment descriptor file contains information
about the service such as the names of the WSDL file, the JAX-RPC
mapping file, and also the service endpoint interface and the service
implementation class names.
© Sun Microsystems 2005. All of the material in The
Java BluePrints Solutions Catalog is copyright-protected
and may not be published in other works without express written
permission from Sun Microsystems.