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

