Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting raw XML SOAP-response on client side using ADB-stubs created by AXIS2

Tags:

java

soap

axis2

I access a SOAP service using ADB-stubs created by AXIS2. I would like to log the raw XML response of any Axis Fault, that is returned by the service. I can catch those errors as "ServiceError". However, I do not find a way to retreive the raw XML (see example below).

I found a way to access the raw XML request / response for regular processing, using getOMElement (see example below). However, this does not work for faults.

How do I get the raw XML fault using ADB stubs?

Example Java code:

    public void testRequest(String URL) throws AxisFault {
        MyServiceStub myservice = new MyServiceStub(URL);
        MyRequest req = new MyRequest();
        try {
            TypeMyFunctionResponse response = myservice.myFunction(req);

            // logging full soap response
            System.out.println("SOAP Response: "
                    + response.getOMElement(null,
                            OMAbstractFactory.getOMFactory())
                            .toStringWithConsume());
        } catch (RemoteException e) {
            //...
        } catch (ServiceError e) {
            // how to get the raw xml?
        }
    }

Example fault response, that I would like to fetch and log:

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Body>
        <soapenv:Fault>
            <soapenv:Code>
                <soapenv:Value>soapenv:Receiver</soapenv:Value>
            </soapenv:Code>
            <soapenv:Reason>
                <soapenv:Text xml:lang="en-US">service error</soapenv:Text>
            </soapenv:Reason>
            <soapenv:Detail>
                <ns1:error xmlns:ns1="http://www.somehost.com/webservices/someservice">
                    <ns1:code>500</ns1:code>
                    <ns1:messageText>some fault message</ns1:messageText>
                </ns1:error>
            </soapenv:Detail>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>
like image 800
Daniel Avatar asked Aug 29 '12 09:08

Daniel


2 Answers

Below is what you probably are looking for, yourStub is what you generated via wsdl2java and use below lines after you make your request. The message is set to lastOperation and sends it when you make the actual call:

request = yourStub._getServiceClient().getLastOperationContext().getMessageContext("Out")
              .getEnvelope().toString());

response = yourStub._getServiceClient().getLastOperationContext().getMessageContext("In")
              .getEnvelope().toString());

Hope that was helpful.

like image 194
Ducane Avatar answered Nov 07 '22 22:11

Ducane


While this question is already answered well, I needed to do this earlier and had trouble finding a suitable answer that fit my constraints so I'm adding my own for posterity.

I needed to do this with Axis 2 version 1.4.1 for a recent project running JDK 1.4, which from what I'd read was not supported by the JAX-WS stubs. I ended up keeping the ADB stubs while capturing the input by wrapping SoapBuilder with my own builder class, copying the input stream and passing the copy to the SoapBuilder:

public class SOAPBuilderWrapper implements Builder {
    private String lastResponse;

    private SOAPBuilder builder = new SOAPBuilder();

    private static final int BUFFER_SIZE = 8192;

    public OMElement processDocument(InputStream inputStream,
            String contentType, MessageContext messageContext) throws AxisFault {
        ByteArrayOutputStream copiedStream = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = inputStream.read(buffer);
            while (bytesRead > -1) {
                copiedStream.write(buffer, 0, bytesRead);
                bytesRead = inputStream.read(buffer);
            }
            lastResponse = copiedStream.toString();

        } catch (IOException e) {
            throw new AxisFault("Can't read from input stream", e);
        }
        return builder.processDocument(
                new ByteArrayInputStream(copiedStream.toByteArray()),
                contentType, messageContext);
    }

    public String getLastResponse() {
        return lastResponse;
    }
}

For various reasons, configuring using axis2.xml was problematic, so the wrapper was added programmatically with the following:

SoapBuilderWrapper responseCaptor = new SoapBuilderWrapper();
AxisConfiguration axisConfig = stub._getServiceClient().getAxisConfiguration();
axisConfig.addMessageBuilder("application/soap+xml", responseCaptor);
axisConfig.addMessageBuilder("text/xml", responseCaptor);

This allows responses to be retrieved using responseCaptor.getLastResponse() after the service is invoked.

like image 5
Taufiq Avatar answered Nov 07 '22 23:11

Taufiq