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 > 3 <xsd:sequence> 4 <xsd:element minOccurs=’1′ maxOccurs=’1′ name=’name‘ type=’xsd:string’/> 5 =’1′ maxOccurs=’1′ name=’requestXMLData‘ type=’xsd:anyType’/> 6 > 7 xsd:complexType> 8 xsd:element> 9 <xsd:element name=’testXMLCallResponse’> 10 > 11 <xsd:sequence> 12 <xsd:element minOccurs=’1′ maxOccurs=’1′ name=’responseXMLData‘ type=’xsd:anyType’/> 13 > 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.net/