The WSDL file describes the web service. Please note an application-defined service exception declared in the WSDL. A snippet from the WSDL for this service would look like this:
<><types>
<schema
targetNamespace="urn:StringPurchaseOrderService"
xmlns:tns="urn:StringPurchaseOrderService"
xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="submitPO">
<sequence>
<element
name="String_1" type="string" nillable="true"/>
</sequence>
</complexType>
<complexType
name="submitPOResponse">
<sequence>
<element
name="result" type="string" nillable="true"/>
</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="StringPurchaseOrderServiceSEI_submitPO">
<part name="parameters"
element="tns:submitPO"/>
</message>
<message
name="StringPurchaseOrderServiceSEI_submitPOResponse">
<part name="result"
element="tns:submitPOResponse"/>
</message>
<message name="InvalidPOException">
<part name="InvalidPOException"
element="tns:InvalidPOException"/>
</message>
<portType name="StringPurchaseOrderServiceSEI">
<operation name="submitPO">
<input
message="tns:StringPurchaseOrderServiceSEI_submitPO"/>
<output
message="tns:StringPurchaseOrderServiceSEI_submitPOResponse"/>
<fault name="InvalidPOException"
message="tns:InvalidPOException"/>
</operation>
</portType>
Code Example 1: Snippet From the WSDL for the Service
>
public interface StringPurchaseOrderServiceSEI extends Remote
{
public String submitPO(String xmlPO)
throws InvalidPOException, RemoteException;
}
Code Example 2: The Service Endpoint InterfacegetID()
returns only the purchase order
ID
to the client. In a real world scenario, there will be some work that
needs to be done before returning the result to the client, but we are
not focusing on business logic. Also, please note the endpoint first
validates the document against its schema.An important point to notice
is that
the purchase order XML is handled as a String. The endpoint
implementation class would look like this:public class StringPurchaseOrderServiceBean implements
SessionBean {
private SessionContext sc;
private DocumentBuilderFactory docBuilderFactory;
public StringPurchaseOrderServiceBean(){}
public String submitPO(String xmlPO) throws
InvalidPOException, RemoteException {
String id =null;
if (!(validate(xmlPO))) {
throw new InvalidPOException("Error parsing the purchase order XML
document!!!");
}
try {
//extract the PO ID from the document and return to the client
id =
getID(xmlPO);
} catch (Exception e) {
throw new EJBException("StringPurchaseOrderService implementation had
trouble parsing PO.xml, some system or
configuration problem " + 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 id;
}
private String getID(String xmlDoc) throws
org.xml.sax.SAXException,
javax.xml.parsers.ParserConfigurationException,
java.io.IOException {
String ret = "";
DocumentBuilder db = null;
if (docBuilderFactory !=
null)
db =
docBuilderFactory.newDocumentBuilder();
InputSource is = new
InputSource(new StringReader(xmlDoc));
Document doc = db.parse(is);
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) return
child.getNodeValue();
}
}
return ret;
}
private boolean validate(String xmlDoc) {
Document doc = null;
try {
DocumentBuilderFactory dbf = null;
DocumentBuilder db = null;
try {
dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
dbf.setNamespaceAware(true);
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
if (dbf != null){
db = dbf.newDocumentBuilder();
}
db.setEntityResolver(new POEntityResolver());
db.setErrorHandler(new POXMLErrorHandler());
}
catch ( javax.xml.parsers.ParserConfigurationException pce) {
System.err.println(pce);
}
InputSource is = new InputSource(new StringReader(xmlDoc));
doc
= db.parse(is);
return true;
} catch (Exception e) {
System.err.println("XML Validation Error " + e);
}
return false;
}
//life cycle methods
...
}
Code Example 3: The Endpoint Implementation<enterprise-beans>
<session>
<ejb-name>StringPurchaseOrderServiceBean</ejb-name>
<service-endpoint>
com.sun.j2ee.blueprints.stringposervice.StringPurchaseOrderServiceSEI
</service-endpoint>
<ejb-class>
com.sun.j2ee.blueprints.stringposervice.StringPurchaseOrderServiceBean
</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
Code Example 4: 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 that looks like this: <webservice-description>
<webservice-description-name>StringPurchaseOrderService</webservice-description-name>
<wsdl-file>META-INF/wsdl/StringPurchaseOrderService.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/stringpurchaseorderservice-mapping.xml</jaxrpc-mapping-file>
<port-component>
<description>port component
description</description>
<port-component-name>StringPurchaseOrderService</port-component-name>
<wsdl-port
xmlns:PurchaseOrderns="urn:StringPurchaseOrderService">PurchaseOrderns:StringPurchaseOrderServiceSEIPort</wsdl-port>
<service-endpoint-interface>
com.sun.j2ee.blueprints.stringposervice.StringPurchaseOrderServiceSEI
</service-endpoint-interface>
<service-impl-bean>
<ejb-link>StringPurchaseOrderServiceBean</ejb-link>
</service-impl-bean>
</port-component>
</webservice-description>
Code Example 5: 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 and the JAX-RPC
mapping
file, and also the service endpoint interface and the service
implementation class names.