The WSDL file describes the web service. Code Example 1 contains the WSDL for this service. The development style we chose for this application 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, because these types will result in the types of the parameters in the generated Java code. Please note an application defined service exception declared in the WSDL.
Let's look at some detail in the type for the purchase order being
received and the short xml message being returned, both as attachments
but using different types. Note that the schema for attachments was
imported with <import
namespace="http://ws-i.org/profiles/basic/1.1/xsd"
schemaLocation="WS-ISwA.xsd"/>
in the WSDL file. This enables
the short XML document containing a purchase order ID that is returned
from the service as an attachment to use this type. It uses wsi:swaRef
to reference the type defined in that schema file. For the purchase
order documents to be received by the service on the submitPO
operation, notice that it uses the xsd:hexBinary for its type and in
its binding it specifies the MIME content type to text/xml. By choosing
this MIME type, it causes the JAX-RPC runtime to map it to a Java
javax.xml.transform.Source
object. These two different types for attachments are mapped to two
different Java types when this WSDL file is used to generate the Java
interface in Code Example 3.
<?xml
version="1.0" encoding="UTF-8"?>
<definitions xmlns:tns="urn:AttachmentPurchaseOrderService"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="urn:AttachmentPurchaseOrderService"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
targetNamespace="urn:AttachmentPurchaseOrderService"
name="AttachmentPurchaseOrderService">
<types>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:AttachmentPurchaseOrderService">
<import
namespace="http://ws-i.org/profiles/basic/1.1/xsd"
schemaLocation="WS-ISwA.xsd"/>
<element name="statusmessage"
type="wsi:swaRef"/>
<element name="InvalidPOException"
type="string"/>
</schema>
</types>
<message
name="AttachmentPurchaseOrderServiceSEI_submitPO">
<part
name="attachment_1" type="xsd:hexBinary"/>
</message>
<message
name="AttachmentPurchaseOrderServiceSEI_submitPOResponse">
<part name="response"
element="ns1:statusmessage"/>
</message>
<message
name="InvalidPOException">
<part
name="InvalidPOException" element="ns1:InvalidPOException"/>
</message>
<portType
name="AttachmentPurchaseOrderServiceSEI">
<operation name="submitPO">
<input
message="tns:AttachmentPurchaseOrderServiceSEI_submitPO"/>
<output
message="tns:AttachmentPurchaseOrderServiceSEI_submitPOResponse"/>
<fault name="InvalidPOException"
message="tns:InvalidPOException"/>
</operation>
</portType>
<binding
name="AttachmentPurchaseOrderServiceSEIBinding"
type="tns:AttachmentPurchaseOrderServiceSEI">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="submitPO">
<input>
<mime:multipartRelated>
<mime:part>
<soap:body
use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attachment_1" type="text/xml"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body
parts="response" use="literal"/>
</mime:part>
</mime:multipartRelated>
</output>
<fault name="InvalidPOException">
<soap:fault name="InvalidPOException"
use="literal"/>
</fault>
</operation>
</binding>
<service name="AttachmentPurchaseOrderService">
<port
name="AttachmentPurchaseOrderServiceSEIPort"
binding="tns:AttachmentPurchaseOrderServiceSEIBinding">
<soap:address
location="http://localhost:8080/webservice/AttachmentPurchaseOrderService"/>
</port>
</service>
</definitions>
Code Example 1: Snippet From the WSDL for the Service Using
Attachments to Exchange XML Documents
Notice that the WSDL file in Code
Example
1 imports the schema for SOAP with Attachments. This schema is
fairly short, so let's take a look at it. Code
Example 2 contains the schema which is imported. This schema
creates
a type called wsi:swaRef
which is based on xsd:anyURI.
Code Example 2: Schema for SOAP With Attachments<?xml version="1.0"
encoding="utf-8" ?>
<!-- July, 2002
(c) Copyright 2003, The Web
Services-Interoperability Organization (WS-I)
Download or use of this file is governed by the
Policies and Bylaws of WS-I.
For more information, send email info@ws-i.org.
-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://ws-i.org/profiles/basic/1.1/xsd"
xmlns:tns="http://ws-i.org/profiles/basic/1.1/xsd">
<xsd:simpleType name="swaRef">
<xsd:restriction
base="xsd:anyURI" />
</xsd:simpleType>
</xsd:schema>
submitPO()
method that accepts a
javax.xml.transform.Source
object. Also, the application defined exception InvalidPOException
is generated from the WSDL. Notice that it returns a java.net.URI
type for the wsi:swaRef attachment type using the Attachment Profile
schema, and for the purchase order XML document received as an
attachment specified using the xsd:hexBinary type, it uses the
javax.xml.transform.Source type. public interface
AttachmentPurchaseOrderServiceSEI extends Remote {
public URI submitPO(Source attachment_1) throws
InvalidPOException,
RemoteException;
}
Code Example 3: The Service Endpoint Interfacepublic class
AttachmentPurchaseOrderServiceBean implements SessionBean {
private SessionContext sc;
private TransformerFactory transfactory;
public AttachmentPurchaseOrderServiceBean() {}
/**
* This method implements a web service that
processes an XML purchase
* order document it receives as an attachment
* and returns a WS-I Attachment profile
conformat message
* using the swaRef data type
*/
public java.net.URI submitPO(Source xmlsrc) throws
InvalidPOException, RemoteException{
URI uri = null;
String id = null;
try {
Transformer transformer = transfactory.newTransformer();
DOMResult result = new DOMResult();
transformer.transform(xmlsrc, result);
Document doc = (Document)result.getNode();
Element root = doc.getDocumentElement();
NodeList list = root.getElementsByTagName("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();
}
}
MessageContext mc = sc.getMessageContext();
AttachmentPart att =
MessageFactory.newInstance().createMessage().createAttachmentPart();
att.setContentId(" < "+ id + " >");
att.setContent("<submitPO response/>","text/plain");
ArrayList arrList = new ArrayList();
arrList.add(att);
//
app server implementation specific
mc.setProperty("com.sun.xml.rpc.attachment.SetAttachmentContext",
arrList);
uri
= new java.net.URI("cid:" + id);
} catch (Exception e) {
throw new EJBException("AttachmentPOService Having
Problems:"+e.getMessage(), e);
}
//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 uri;
}
//life cycle methods
...
}
Code Example 4: The Endpoint Implementation Java Classpublic class
AttachmentPOServiceBD {
...
public String submitPO(PurchaseOrder po) throws
RequestHandlerException {
try {
AttachmentPurchaseOrderServiceSEI port =
(AttachmentPurchaseOrderServiceSEI)
serviceLocator.getServicePort(JNDINames.ATTACHMENT_SERVICE_REF,
AttachmentPurchaseOrderServiceSEI.class);
String xmlDoc = po.toXMLString();
Source src = new StreamSource(new StringReader(xmlDoc));
URI
resp= port.submitPO(src);
return resp.getSchemeSpecificPart();
} catch(InvalidPOException
ipe){
...
}
}
<enterprise-beans>
<session>
<ejb-name>AttachmentPurchaseOrderServiceBean</ejb-name>
<service-endpoint>com.sun.j2ee.blueprints.attachmentservice.AttachmentPurchaseOrderServiceSEI</service-endpoint>
<ejb-class>com.sun.j2ee.blueprints.attachmentservice.AttachmentPurchaseOrderServiceBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
Code Example 6: Snippet From ejb-jar.xml Deployment
Descriptor<service-endpoint>
in ejb-jar.xml. The endpoint also needs a web services deployment
descriptor file, webservices.xml, such as in Code Example 5. Notice
there is nothing special to do in the deployment descriptor when using
attachments. <webservice-description>
<webservice-description-name>AttachmentPurchaseOrderService</webservice-description-name>
<wsdl-file>META-INF/wsdl/AttachmentPurchaseOrderService.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/attachmentpurchaseorderservice-mapping.xml</jaxrpc-mapping-file>
<port-component>
<description>port component
description</description>
<port-component-name>AttachmentPurchaseOrderService</port-component-name>
<wsdl-port
xmlns:PurchaseOrderns="urn:AttachmentPurchaseOrderService">PurchaseOrderns:AttachmentPurchaseOrderServiceSEIPort</wsdl-port>
<service-endpoint-interface>
com.sun.j2ee.blueprints.attachmentservice.AttachmentPurchaseOrderServiceSEI
</service-endpoint-interface>
<service-impl-bean>
<ejb-link>AttachmentPurchaseOrderServiceBean</ejb-link>
</service-impl-bean>
</port-component>
</webservice-description>
Code Example 7: Snippet From webservice.xml Deployment
Descriptor