JAX-WS: How to input and output XML AnyType

JAX-WS works in a very simple and effective way if you have defined all objects in a XML Schema definition. But sometimes you can’t define a schema for an operation because e.g. it is a generic operation and accepts or returns dynamic XML.

Nevertheless we would like to use for this operation the same tool chain with JAX-WS which is working perfectly for other operations.

In the first step we define the interface of the operation testXMLCall in the WSDL (better the XSD referenced by the WSDL).

1 <xsd:element name=’testXMLCall‘> 2 <xsd:complexType> 3 <xsd:sequence> 4 <xsd:element minOccurs=’1′ maxOccurs=’1′ name=’name‘ type=’xsd:string’/> 5 <xsd:element minOccurs=’1′ maxOccurs=’1′ name=’requestXMLData‘ type=’xsd:anyType’/> 6 </xsd:sequence> 7 </xsd:complexType> 8 </xsd:element> 9 <xsd:element name=’testXMLCallResponse‘> 10 <xsd:complexType> 11 <xsd:sequence> 12 <xsd:element minOccurs=’1′ maxOccurs=’1′ name=’responseXMLData‘ type=’xsd:anyType’/> 13 </xsd:sequence> 14 </xsd:complexType> 15 </xsd:element>

From this WSDL we generate the interface PortType of the webservice. The implementation of the interface needs an operation of this definition:

1 @WebMethod(action = http://localhost/testXMLCall) 2 @WebResult(name = responseXMLData, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 3 @RequestWrapper(localName = testXMLCall, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1, className = com.oc.soa.sample.ws.v1.messages.TestXMLCall) 4 @ResponseWrapper(localName = testXMLCallResponse, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1, className = com.oc.soa.sample.ws.v1.messages.TestXMLCallResponse) 5 public Object testXMLCall( 6 @WebParam(name = name, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 7 String name, 8 @WebParam(name = requestXMLData, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 9 Object requestXMLData);

We make an implementation:

1 @WebMethod(action = http://localhost/testXMLCall) 2 @WebResult(name = responseXMLData, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 3 @RequestWrapper(localName = testXMLCall, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1, className = com.oc.soa.sample.ws.v1.messages.TestXMLCall) 4 @ResponseWrapper(localName = testXMLCallResponse, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1, className = com.oc.soa.sample.ws.v1.messages.TestXMLCallResponse) 5 public Object testXMLCall( 6 @WebParam(name = name, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 7 String name, 8 @WebParam(name = requestXMLData, targetNamespace = http://opitz-consulting.com/interfaces/TestMessages/V1) 9 Object requestXMLData) { 10 TestXMLCallResponse result = new TestXMLCallResponse(); 11 if (requestXMLData instanceof Element) { 12 Element requestXMLDataElement = ((Element) requestXMLData); 13 LOG.info(XML in: \n + getPrintString(requestXMLDataElement)); 14 XmlObject xmlResult; 15 try { 16 xmlResult = doSomething(requestXMLDataElement); 17 } catch (RuntimeException e) { 18 LOG.error(Error while doSomething with XML: \n + getPrintString(requestXMLDataElement), e); 19 throw e; 20 } 21 LOG.info(XML out: \n + getPrintString(xmlResult.getDomNode())); 22 result.setResponseXMLData(xmlResult.getDomNode().getFirstChild()); 23 } else if (requestXMLData == null) { 24 LOG.error(Data is null. ); 25 } else { 26 LOG.error(Unknown data of type ‚+ requestXMLData.getClass() + ‚. ); 27 } 28 return result; 29 }

We make an implementation of the method getPrintString for a readable output of the XML.

1 public static String getPrintString(Node node) { 2 try { 3 DOMSource domSource = new DOMSource(node); 4 StringWriter writer = new StringWriter(); 5 StreamResult result = new StreamResult(writer); 6 TransformerFactory tf = TransformerFactory.newInstance(); 7 Transformer transformer = tf.newTransformer(); 8 transformer.transform(domSource, result); 9 writer.flush(); 10 return writer.toString(); 11 } catch (TransformerException e) { 12 LOG.warn(Unable to convert XML-Node ‚ + node.toString() + ‚ of class ‚ + node.getClass() + ‚ to string representation., e); 13 return [non printable xml]; 14 } 15 }

And finally the method doSomething processing the xml element and returning an XmlObject needs to be implemented.

Bernhard Mähr @ OPITZ-CONSULTING published at https://thecattlecrew.wordpress.com/

Über bmaehr

Ich bin ein Technik-Fan, der in der Informatik seinen Beruf und seine Berufung gefunden hat.
Dieser Beitrag wurde unter BPM & System Integration abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s