Wednesday 13 June 2012

Sending SOAP message as plain XML with java

 

There are many Java implementations for working with web services, but all of them request having some heavy framework (e.g. AXIS).  You need to generate proxy classes figure how to use them and eventually you finish with 20MB program that maybe does something very simple like calling a web  - service that converts money from US dollar to Euro.

So I will show how can you use only Java core classes without any additional libraries and send SOAP message as plain XML text.

//create URL object
URL url = new URL( "http://someurl.com/soap" );
rc
= (HttpURLConnection)url.openConnection();
//you need to check if server expects POST or GET
//but to be honest I never saw web-service expecting GET reqiest

rc.setRequestMethod(
"POST");
rc.setDoOutput(
true );
rc.setDoInput(
true );
//it is very important to specify the content type. Web-service will reject the request if it is
//not XML
rc.setRequestProperty( "Content-Type", "text/xml; charset=utf-8" );
//and here comes some dummy SOAP message
String reqStr = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ord=\"http://someurl.com/OfflineBatchSync/Order\">"+
"<soapenv:Header/>"+
"<soapenv:Body>"+
" <ord:CreateOrderHeader_Input>"+
" <ord:CustomerPO></ord:CustomerPO>"+
" <ord:SubOrderType>VMI</ord:SubOrderType>"+
" <ord:PreSaleFlg></ord:PreSaleFlg>"+
" <ord:DistributorId></ord:DistributorId>"+
" <ord:AccountId>1-6T4N</ord:AccountId>"+
" <ord:OrderStatus></ord:OrderStatus>"+
" <ord:RequestedDate></ord:RequestedDate>"+
" <ord:ShipInstructions></ord:ShipInstructions>"+
" <ord:PriceListId></ord:PriceListId>"+
" </ord:CreateOrderHeader_Input>"+
"</soapenv:Body>"+
"</soapenv:Envelope>";
//several more definitions to request
int len = reqStr.length();
rc.setRequestProperty(
"SOAPAction:", "\"document/http://someurl.com/OfflineBatchSync/Order:CreateOrderHeader\"" );
rc.setRequestProperty(
"Content-Length", Integer.toString( len ) );
rc.setRequestProperty(
"Connection:", "Keep-Alive" );
rc.connect();
//write XML to the server
OutputStreamWriter outStr = new OutputStreamWriter( rc.getOutputStream() );
outStr.write( reqStr,
0, len );
outStr.flush();

/* Here is the important part, if something goes wrong and excetion will
* be thrown and you will have some meaningless exception saying blah.. blahh HTTP 500
* which actually doesn't tell you a lot about what happen.
* However most web-services provide as a response some error page that displays what
* was wrong. It whould be nice to see this page instead of stupid HTTP 500.
* It is not difficult . All you need is actually read not the response stream , but the error stream
*/

try
{
read
= new InputStreamReader( rc.getInputStream() );
}
catch(Exception exception)
{
//if something wrong instead of the output, read the error
read = new InputStreamReader( rc.getErrorStream() );
}

//read server response
StringBuilder sb = new StringBuilder();
int ch = read.read();
while( ch != -1 ){
sb.append((
char)ch);
ch
= read.read();
}
String responseTr
= sb.toString();



Basically this is all you need . After execution of the code above responseTr  variable will hold the response SOAP message in case of success or response error (In case of error it will be HTML script so you may want to display it in browser or to strip HTML tags)