WSDL 文件对 Web 服务进行了描述。代码示例 1 包含了此服务的 WSDL。我们选择开发此应用程序的形式是从 WSDL 开始的,并基于 WSDL 生成必要的 Java[TM] 类。因此,为消息部分在 WSDL 中选择正确的类型是非常重要的,因为这些类型会在生成的 Java 代码中产生参数类型。请注意在 WSDL 中声明的应用程序定义的服务异常。
让我们看一下接收订单以及返回 xml 短消息所使用的类型,它们都作为附件但使用不同的类型。请注意,在 WSDL 文件中,附件的结构是使用
导入的。这样,作为附件从服务返回的、包含订单 ID 的 XML 短文档就可以使用此类型了。它使用 wsi:swaRef 引用该结构文件中定义的类型。对于 submitPO 操作中要由服务接收的订单文档,请注意该文档使用了 xsd:hexBinary 作为其类型,并在其绑定中将 MIME 内容类型指定为 text/xml。通过选择此 MIME 类型,会通过 JAX-RPC 运行环境将其映射到 Java javax.xml.transform.Source
对象中。使用此 WSDL 文件生成代码示例 3 中的 Java 接口时,附件的这两种不同类型被映射到两种不同的 Java 类型了。
<?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>
代码示例 1:使用附件交换 XML 文档的服务 WSDL 中的代码片段
请注意,代码示例 1 中的 WSDL 文件导入了使用附件的 SOAP 结构。此结构很简短,让我们来了解一下。代码示例 2 包含了导入的结构。此结构创建了一个名为 wsi:swaRef
的类型,该类型基于 xsd:anyURI。
代码示例 2:使用附件的 SOAP 结构<?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>
javax.xml.transform.Source
对象的 submitPO()
方法。此外,还会从 WSDL 生成应用程序定义的异常 InvalidPOException
。请注意,对于使用附件配置文件结构的 wsi:swaRef 附件类型,它返回 java.net.URI 类型,而对于订单 XML 文档(作为使用 xsd:hexBinary 类型的附件接收),它使用 javax.xml.transform.Source 类型。public interface
AttachmentPurchaseOrderServiceSEI extends Remote {
public URI submitPO(Source attachment_1) throws
InvalidPOException,
RemoteException;
}
代码示例 3:服务端点接口public 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
...
}
代码示例 4:端点实现 Java 类public 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>
代码示例 6:ejb-jar.xml 部署描述符中的代码片段<service-endpoint>
。端点还需要 Web 服务部署描述符文件 webservices.xml,如代码示例 5 所示。请注意在使用附件时不需要对部署描述符执行任何特殊的操作。 <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>
代码示例 7:webservice.xml 部署描述符中的代码片段