Accessing SOAP server programatically with a client

Hi!

I have found lots of documentation on how to send messages to a SOAP server when the xml is already specified. A lot less is written how this should be done programatically, and I can't find the solution to my problem. (I think doing it programatically is more pretty....)

So, I got my web server up and running (JBoss 4.0.5GA), and the web service is deployed as it should (I've tested it using hard-coded ws request, which succeed).

I also got a bunch of java files generated using wsdl2java, which I am using to create my request. The first thing I want to do is a simple login.

The code (stripped a bit for convenience):

publicvoid run()

throws AxisFault, InterruptedException{

// set up some initial stuff

SOAPFactory factory =new SOAP12Factory();

Options options =new Options();

options.setTo(mTargerEPR);

// log in to the system

SOAPEnvelope payload = createLoginDocument(factory);

// set the action to use for this call

options.setAction("CAI3G#Login");

// Non-Blocking Invocation

ServiceClient sender =new ServiceClient();

sender.setOptions(options);

process(payload, sender);

}

private SOAPEnvelope createLoginDocument(SOAPFactory factory){

LoginDocument loginDocument = LoginDocument.Factory.newInstance();

LoginDocument.Login login = loginDocument.addNewLogin();

login.setUserId("admin");

login.setPwd("admin");

return toEnvelope(factory, loginDocument);

}

private SOAPEnvelope toEnvelope(SOAPFactory factory, XmlObject document){

SOAPEnvelope envelope = factory.createSOAPEnvelope();

// create the header, which must contain sequence id and session id

factory.createSOAPHeader(envelope);

if (document !=null){

// create the body and include the document provided

SOAPBody body = factory.createSOAPBody(envelope);

body.addChild(toOM(document));

}

return envelope;

}

privatestaticvoid process(SOAPEnvelope payload, ServiceClient sender)

throws AxisFault, InterruptedException{

Callback callback =new Callback(){

// currently just print it to test

publicvoid onComplete(AsyncResult result){

System.out.println(result.getResponseEnvelope());

}

publicvoid onError(Exception e){

e.printStackTrace();

}

};

sender.sendReceiveNonBlocking(payload, callback);

// Wait until the callback receives the response.

while (!callback.isComplete()){

Thread.sleep(1000);

}

}

The error I receive looks like this:

2007-05-29 15:30:03,644 [INFO] Axis2 Task - I/O exception (org.apache.axis2.AxisFault) caught when processing request: Can not output XML declaration, after other output has already been done.

2007-05-29 15:30:03,644 [INFO] Axis2 Task - Retrying request

2007-05-29 15:30:03,644 [INFO] Axis2 Task - I/O exception (org.apache.axis2.AxisFault) caught when processing request: Can not output XML declaration, after other output has already been done.

2007-05-29 15:30:03,644 [INFO] Axis2 Task - Retrying request

2007-05-29 15:30:03,644 [INFO] Axis2 Task - I/O exception (org.apache.axis2.AxisFault) caught when processing request: Can not output XML declaration, after other output has already been done.

2007-05-29 15:30:03,644 [INFO] Axis2 Task - Retrying request

org.apache.axis2.AxisFault: Can not output XML declaration, after other output has already been done.

at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:221)

at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:452)

at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:330)

at org.apache.axis2.description.OutInAxisOperationClient$NonBlockingInvocationWorker.run(OutInAxisOperation.java:405)

at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:665)

at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:690)

at java.lang.Thread.run(Thread.java:619)

...

Caused by: javax.xml.stream.XMLStreamException: Can not output XML declaration, after other output has already been done.

at com.ctc.wstx.sw.BaseStreamWriter.throwOutputError(BaseStreamWriter.java:1473)

at com.ctc.wstx.sw.BaseStreamWriter.reportNwfStructure(BaseStreamWriter.java:1502)

at com.ctc.wstx.sw.BaseStreamWriter.doWriteStartDocument(BaseStreamWriter.java:699)

at com.ctc.wstx.sw.BaseStreamWriter.writeStartDocument(BaseStreamWriter.java:687)

at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:190)

at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMElementImpl.java:808)

at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:779)

at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMElementImpl.java:808)

at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:234)

at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:222)

at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMElementImpl.java:808)

at org.apache.axiom.om.impl.llom.OMNodeImpl.serializeAndConsume(OMNodeImpl.java:418)

at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:55)

... 19 more

In JBoss, I get this exception:

15:30:04,285 ERROR [[localhost]] Exception Processing ErrorPage[errorCode=500, location=/axis2-web/Error/error500.jsp]

org.apache.jasper.JasperException: getOutputStream() has already been called for this response

Any idea/pointer, someone? All help is greatly appreciated!

Best regards,

Peter

[7558 byte] By [pajasa] at [2007-11-27 5:47:32]
# 1

I thought it might be worth to give a printout of the generated xml and the hard-coded, working xml.

The working one:

<env:Envelope

xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:xs="http://www.w3.org/1999/XMLSchema"

xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"

xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"

env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<env:Header />

<env:Body>

<cai3g:Login xmlns:cai3g="http://schemas.ericsson.com/cai3g1.1/">

<cai3g:userId>admin</cai3g:userId>

<cai3g:pwd>admin</cai3g:pwd>

</cai3g:Login>

</env:Body>

</env:Envelope>

The one I've generated, when doing a System.out.println() on the variable payload:

<?xml version='1.0' encoding='utf-8'?>

<soapenv:Envelope

xmlns:xs="http://www.w3.org/1999/XMLSchema"

xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"

xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">

<soapenv:Body>

<Login xmlns="http://schemas.ericsson.com/cai3g1.1/">

<userId>admin</userId>

<pwd>admin</pwd>

</Login>

</soapenv:Body>

</soapenv:Envelope>

pajasa at 2007-7-12 15:32:06 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...