示例:创建一个使用 JAX-WS Web Service 寻址 API 来访问通用 Web Service 资源实例的 Web Service
假定某个 IT 组织有一个打印机网络需要使用 Web Service 进行管理。该组织可将每个打印机表示为可通过端点引用来寻址的一个资源。此示例显示了如何使用由 WebSphere® Application Server 提供的 JAX-WS Web Service 寻址 (WS-Addressing) 应用程序编程接口 (API) 来编写此类服务。
提供返回对目标服务的端点引用的 web service 接口
该 IT 组织实现了提供 CreatePrinter portType 元素的 PrinterFactory 服务。此 portType 元素接受 CreatePrinterRequest 消息以创建表示逻辑打印机的资源,并使用端点引用(对该资源的引用)作出响应。
<wsdl:definitions targetNamespace="http://example.org/printer" ...
xmlns:pr=" http://example.org/printer">
<wsdl:types>
...
<xsd:schema...>
<xsd:element name="CreatePrinterRequest"/>
<xsd:element name="CreatePrinterResponse"
type="wsa:EndpointReferenceType"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="CreatePrinterRequest">
<wsdl:part name="CreatePrinterRequest"
element="pr:CreatePrinterRequest" />
</wsdl:message>
<wsdl:message name="CreatePrinterResponse">
<wsdl:part name="CreatePrinterResponse"
element="pr:CreatePrinterResponse" />
</wsdl:message>
<wsdl:portType name="CreatePrinter">
<wsdl:operation name="createPrinter">
<wsdl:input name="CreatePrinterRequest"
message="pr:CreatePrinterRequest" />
<wsdl:output name="CreatePrinterResponse"
message="pr:CreatePrinterResponse" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
上述示例中的 CreatePrinter 操作返回表示新创建的打印机资源的 wsa:EndpointReference 对象。客户机可以使用此端点引用将消息发送至表示该打印机的服务实例。
实施 web service 接口
以下示例中显示的 createPrinter 方法将获取各打印机资源实例的标识。然后,该操作将创建对打印机服务的端点引用并将打印机标识与端点引用相关联。最后,createPrinter 方法返回端点引用。
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class MyClass {
// Create the printer
...
//Define the printer resource ID as a static constant as it is required in later steps
public static final QName PRINTER_SERVICE_QNAME = new QName("example.printer.com", "printer", "...");
public static final QName PRINTER_ENDPOINT_NAME = new QName("example.printer.com", "PrinterService", "...");
public W3CEndpointReference createPrinter(java.lang.Object createPrinterRequest)
{
Document document = ...;
// Create or lookup the stateful resource and derive a resource
// identifier string.
String resource_identifier = "...";
// Associate this resource identifier with the EndpointReference as
// a reference parameter.
// The choice of name is arbitrary, but should be unique
// to the service.
Element element = document.createElementNS("example.printersample",
"IBM_WSRF_PRINTERID");
element.appendChild( document.createTextNode(resource_identifier) );
...
// Create an EndpointReference that targets the appropriate WebService URI and port name.
// Alternatively, the getEndpointReference() method of the MessageContext can be used.
W3CEndpointReferenceBuilder builder = new W3CEndpointReferenceBuilder();
builder.serviceName(PRINTER_SERVICE_QNAME);
builder.endpointName(PRINTER_ENDPOINT_NAME);
builder.referenceParameter(element);
// The endpoint reference now targets the resource rather than the service.
return builder.build();
}
}
扩展目标服务以便将入局消息与 web service 资源实例相匹配
因为先前描述的 web service 实现,现在,打印机资源实例将一个唯一标识嵌入在其端点引用中。此标识成为引用参数显示在目标为 web service 的后续消息的 SOAP 头中,web service 可以使用该标识将入局消息与相应的打印机相匹配。
Web Service 收到一则包含 WS-Addressing 消息寻址属性的消息后,WebSphere Application Server 将在该消息被分派至应用程序端点之前对这些属性进行处理,并将它们放置到线程上的消息上下文中。打印机 web service 应用程序可访问与 WebServiceContext 对象中的目标端点相关联的引用参数,如以下示例所示:
@Resource
private WebServiceContext context;
...
List list = (List) context.getMessageContext().get(MessageContext.REFERENCE_PARAMETERS);
If your application uses the 2004/08 version of the WS-Addressing specification, use the IBM proprietary API to retrieve the message parameters, as illustrated in the following example.
import com.ibm.websphere.wsaddressing.EndpointReferenceManager;
...
// Initialize the reference parameter name
QName name = new QName(..);
// Extract the String value.
String resource_identifier =
EndpointReferenceManager.getReferenceParameterFromMessageContext(PRINTER_ID_PARAM_QNAME);
Web Service 实现可根据打印机标识将消息转发到相应的打印机实例。
使用端点引用将消息发送至端点
javax.xml.ws.Service jaxwsServiceObject= ...;
W3CEndpointReference epr = ...;
...
Printer myPrinterProxy = jaxwsServiceObject.getPort(epr, Printer.class, new AddressingFeature());
现在,该代理对象表示新的打印机资源实例,并且客户机可以使用该对象通过打印机 Web Service 将消息发送至打印机。当客户机调用该服务时,WebSphere Application Server 会将适当的消息寻址属性添加至消息头,在此情况下为包含在标识目标打印机资源的端点引用中的引用参数。从客户机的角度看,端点引用是不透明的。客户机无法解释任何端点引用参数的内容,因此不应该尝试以任何方式使用这些内容。因为引用参数是服务提供程序私有的,所以客户机无法直接创建端点引用的实例;客户机必须从服务提供程序获取端点引用(例如通过提供程序工厂服务),然后使用这些端点引用将 web service 操作定向至由端点引用表示的端点,如上所示。