Dynamischen Client mit JAX-WS-APIs entwickeln
Java™ API for XML-Based Web Services (JAX-WS) stellt Unterstützung für den dynamischen Aufruf von Serviceendpunktoperationen bereit.
Informationen zu diesem Vorgang
JAX-WS stellt eine neue API für dynamische Dispatch-Clients bereit, die generischer ist und mehr Flexibilität bietet als das vorhandene JAX-RPC-basierte (Java API for XML-based RPC) Dynamic Invocation Interface (DII). Die Dispatch-Clientschnittstelle "javax.xml.ws.Dispatch" ist ein XML-Messaging-orientierter Client, der für fortgeschrittene XML-Entwickler bestimmt ist, die es bevorzugten, auf XML-Ebene mit XML-Konstrukten zu arbeiten. Wenn Sie einen Dispatch-Client schreiben möchten, müssen Sie Erfahrung mit den Dispatch-Client-APIs, den unterstützten Objekttypen und den Nachrichtendarstellungen für die zugehörige WSDL-Datei (Web Services Description Language) haben.
Die Dispatch-API kann Daten im Modus PAYLOAD oder im Modus MESSAGE senden. Wenn Sie den Modus PAYLOAD verwenden, ist der Dispatch-Client nur für die Bereitstellung des Inhalts der Elements <soap:Body> verantwortlich, und JAX-WS fügt die Eingabenutzdaten in ein Element <soap:Envelope> ein. Wenn Sie den Modus MESSAGE verwenden, ist der Dispatch-Client für die Bereitstellung der gesamten SOAP-Rahmenanweisung (Envelope) verantwortlich.
- javax.xml.transform.Source: Verwenden Sie Source-Objekte, um Clients die direkte Verwendung der XML-APIs zu ermöglichen. Sie können Source-Objekte mit SOAP- und HTTP-Bindungen verwenden.
- JAXB-Objekte: Verwenden Sie JAXB-Objekte, sodass Clients die aus einem XML-Schema generierten JAXB-Objekte zum Erstellen und Bearbeiten von XML mit JAX-WS-Anwendungen verwenden können. JAXB-Objekte können nur für SOAP- und HTTP-Bindungen verwendet werden.
- javax.xml.soap.SOAPMessage: Verwenden Sie SOAPMessage-Objekte, sodass Clients mit SOAP-Nachrichten arbeiten können. Sie können SOAPMessage-Objekte nur für SOAP-Bindungen der Version 1.1 oder Version 1.2 verwenden.
- javax.activation.DataSource: Verwenden Sie DataSource-Objekte, sodass Clients mit MIME-Nachrichten (Multipurpose Internet Mail Extension) arbeiten können. DataSource-Objekte können nur für HTTP-Bindungen verwendet werden.
Vorgehensweise
Ergebnisse
Dynamische JAX-WS-Ports, die mit der Servicemethode "addPort" hinzugefügt werden, haben ab WebSphere Application Server Version 8.0 möglicherweise einen zusätzlichen Speicherbedarf. In früheren Releases konnte eine Einzelinstanz eines dynamischen Ports von mehreren Serviceinstanzen gemeinsam genutzt werden. In Version 8.x werden dynamische Ports der Serviceinstanz zugeordnet, von der sie hinzugefügt wurden. Wenn ein JAX-WS-Client mehrere Serviceinstanzen hat, die sich auf einen dynamischen Port desselben Namens beziehen, werden diese Instanzen nicht mehr gemeinsam genutzt. Das kann den Speicherbedarf dieses Clients erhöhen. Der Speicher, der von dynamischen Ports belegt wird, wird freigegeben, wenn die Serviceinstanz ihren Geltungsbereich verlässt. Sollten im Zusammenhang mit dem erhöhten Speicherbedarf Probleme auftreten, kann das Verhalten zurückgesetzt werden. Dann werden dynamische Ports wieder von mehreren Serviceinstanzen gemeinsam genutzt. Dazu müssen Sie für die Systemeigenschaft jaxws.share.dynamic.ports.enable den Wert true festlegen. Beachten Sie, dass dieser Vorgang andere Probleme nach sich ziehen kann, wie z. B. die falsche Anwendung von Richtliniensatzzuordnungen bei gemeinsam genutzten Ports. Wenn Sie dieses Flag auf true setzen und Probleme auftreten, sollten Sie die Flageinstellung zurücksetzen.
Wenn in früheren Releases keine SOAP-Aktion von der Dispatch-Clientanwendung bereitgestellt wurde, wurde in der abgehenden Nachricht nicht die richtige SOAP-Aktion gesendet. Stattdessen wurde eine anonyme Operation als SOAP-Aktion festgelegt. Seit WebSphere Application Server Version 8 parst die JAX-WS-Laufzeitumgebung die abgehende Nachricht, falls die SOAP-Aktion nicht von der Dispatch-Clientanwendung bereitgestellt wird. Die Laufzeitumgebung ermittelt die aufzurufende Operation und verwendet diese Information, um den richtigen Wert für die SOAP-Aktion zu bestimmen. Die Auflösung der Operation basiert auf dem SOAP-Hauptteil und der Nachrichtencodierung, z. B.: Doc/Lit/Bare, Doc/Lit/Wrapped. Dieses Parsing kann kostenintensiv sein, daher besteht die Möglichkeit, eine Eigenschaft festzulegen. Um das Parsing zu inaktivieren, müssen Sie die Eigenschaft auf Systemebene festlegen. Um das Parsing pro Nachricht zu inaktivieren, müssen Sie die Eigenschaft im Kontext der JAX-WS-Anforderungsnachricht festlegen. Die Eigenschaft wird als Konstante vom Typ org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION mit dem Zeichenfolgewert jaxws.dispatch.outbound.operation.resolution.enable definiert. Der Standardwert dieser Eigenschaft ist "null" und wird als true interpretiert. Damit wird die Auflösung abgehender Operationen aktiviert. Wenn den Wert false für die Eigenschaft festlegen, wird die Auflösung der abgehenden Operation inaktiviert. Bei inaktiviertem Parsing wird, wie in früheren Releases, in der abgehenden Nachricht eine anonyme Operation als SOAP-Aktion festgelegt. Wenn der Client eine SOAP-Aktion über die JAX-WS-Eigenschaften vom Typ javax.xml.ws.BindingProvider SOAPACTION_USE_PROPERTY und SOAPACTION_URI_PROPERTY bereitstellt, wird diese SOAP-Aktion verwendet. Daher wird unabhängig von der Einstellung der Eigenschaft kein Parsing der abgehenden Nachricht ausgeführt. Insbesondere hinsichtlich der Leistung im Service-Provider hat es sich bewährt, eine SOAP-Aktion explizit vom Client festlegen zu lassen. Bei dieser Vorgehensweise wird die eingehende Nachricht nicht geparst, und sie wird an die richtige Endpunktoperation weitergeleitet.
Beispiel
String endpointUrl = ...;
QName serviceName = new QName("http://com/ibm/was/wssample/echo/",
"EchoService");
QName portName = new QName("http://com/ibm/was/wssample/echo/",
"EchoServicePort");
/** Service erstellen und mindestens einen Port hinzufügen. **/
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
/** Dispatch-Instanz aus einem Service erstellen **/
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE);
/** SOAPMessage-Anforderung erstellen **/
// Anforderungsnachricht erstellen
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
// Nachricht erstellen. In diesem Beispiel wird mit SOAPPART gearbeitet.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();
// SOAPEnvelope sowie Header- und Hauptteilelemente abrufen
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();
// Nachrichtennutzdaten erstellen
SOAPElement operation = body.addChildElement("invoke", "ns1",
"http://com/ibm/was/wssample/echo/");
SOAPElement value = operation.addChildElement("arg0");
value.addTextNode("ping");
request.saveChanges();
/** Serviceendpunkt aufrufen **/
SOAPMessage response = dispatch.invoke(request);
/** Antwort verarbeiten **/