Monday, April 12, 2010

customized web service invocation with one bpm tool

Lately, I've been working on a customized java service for one bpm tool (Cordys) to invoke platform web services. Here are the implementation details:
1. A method that takes xml message as a string:
public static String invoke(String endpoint, String userName, String password,
String requestMessage) {
SOAPMessage soapResponse = invoke(endpoint, userName, password,
convertStringToSoapMessage(requestMessage));

return convertSoapMessageToString(soapResponse);
}

2. A method that handles SoapMessage data type:
public static SOAPMessage invoke(String endpoint, String userName,
String password, SOAPMessage soapMsg) {
try {
// Create the connection
SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory
.newInstance();
SOAPConnection conn = soapConnFactory.createConnection();

CordysAuthenticator credential = new CordysAuthenticator(userName, password);
// CordysAuthenticator is an "Authenticator" implementation
Authenticator.setDefault(credential);

SOAPMessage soapResponse = conn.call(soapMsg, endpoint);
conn.close();
return soapResponse;
} catch (SOAPException e) {
System.out.println("SOAPException : " + e);
return null;

}
}

3. A method to convert String to SoapMessage:
public static SOAPMessage convertStringToSoapMessage(String requestString) {

try {

// Use SAAJ to convert Document to SOAPElement
// Create SoapMessage
MessageFactory msgFactory = MessageFactory.newInstance();
SOAPMessage message = msgFactory.createMessage();
SOAPPart part=message.getSOAPPart();

byte[] soapBytes=requestString.getBytes();
ByteArrayInputStream stream = new ByteArrayInputStream(soapBytes);
StreamSource source = new StreamSource(stream);
part.setContent(source);
message.saveChanges();

// This returns the SOAPBodyElement
// that contains ONLY the Payload
System.out.print("request message String:"+ requestString);
return message;

} catch (SOAPException e) {
System.out.println("SOAPException : " + e);
return null;

}

}

4. A method to convert SoapMessage to string
public static String convertSoapMessageToString(SOAPMessage soapMessage) {
try {
String result = "";

// Create transformer
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
// TransformerConfigurationException


// Get reply content
Source sourceMsg = soapMessage.getSOAPPart().getContent();
// SOAPException

// Set output transformation
StringWriter writer = new StringWriter();
StreamResult resultStream = new StreamResult(writer);
transformer.transform(sourceMsg, resultStream);
// TransformerException
result = writer.toString();
writer.close();
// IOException

return convertToXmlString(result);
} catch (...){}
}


There might be error message such as "invalid soap messages" when the message is sent to the web gateway. This might be caused by the doublequote used in the name space declaration of the xml message. In order to solve the problem, we can use the method String.replaceAll("\"","\\\""); to replace doublequotes with escaped doublequotes.