How to convert SOAP XML to Java Object in android - java

I want parse and convert the SOAP XML response to JAVA objects.
I thought of using J-WS and JAXB to do the same by creating the client stub code. But J-WS and JAXB are not part of Android AOSP hence I have to do it manually.
Following is the example of soap xml response.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<SOAP-ENV:Body>
<tds:GetSystemDateAndTime/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Response to device.GetSystemDateAndTime
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:tt="http://www.onvif.org/ver10/schema"
xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
<SOAP-ENV:Body>
<tds:GetSystemDateAndTimeResponse>
<tds:SystemDateAndTime>
<tt:DateTimeType>NTP</tt:DateTimeType>
<tt:DaylightSavings>true</tt:DaylightSavings>
<tt:TimeZone>
<tt:TZ>CET-1CEST,M3.5.0,M10.5.0</tt:TZ>
</tt:TimeZone>
<tt:UTCDateTime>
<tt:Time>
<tt:Hour>15</tt:Hour>
<tt:Minute>52</tt:Minute>
<tt:Second>25</tt:Second>
</tt:Time>
<tt:Date>
<tt:Year>2010</tt:Year>
<tt:Month>10</tt:Month>
<tt:Day>29</tt:Day>
</tt:Date>
</tt:UTCDateTime>
<tt:LocalDateTime>
<tt:Time>
<tt:Hour>17</tt:Hour>
<tt:Minute>52</tt:Minute>
<tt:Second>25</tt:Second>
</tt:Time>
<tt:Date>
<tt:Year>2010</tt:Year>
<tt:Month>10</tt:Month>
<tt:Day>29</tt:Day>
</tt:Date>
</tt:LocalDateTime>
</tds:SystemDateAndTime>
</tds:GetSystemDateAndTimeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

We can use 3rd party SimpleXML framework which uses Apache 2.0license.
For detailed info & examples, refer the below link -
http://simple.sourceforge.net/

Instead of doing it by hand, you should generate the conversion code by using a tool able to understand the wsdl files with the ONVIF specifications.
Since you are talking about java and android, probably you should check ksoap2-android. I am not an expert of java, but there are some examples available, such this one.

Related

SOAP XML request returning "Request is not well formed" fault

I am converting Python code to Java. The code is SOAP 1.5 client code which communicates with a SOAP server endpoint.
What doesn't make sense is that the Python code sends the XML request and gets the accepted response from the server. With the Java code however, the response is a fault stating "Request is not well formed".
Below I am showing the XML requests, the one which is sent in Python and the other in Java. How can the Java one sent by Java return a fault, but the Python is fine / accepted. They are both valid requests. Or perhaps I am missing something obvious.
Request in Python :
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:cs="urn://Ocpp/Cp/2012/06/">
<SOAP-ENV:Header>
<cs:chargeBoxIdentity>Test</cs:chargeBoxIdentity>
<wsa:MessageID>Fake OCPP571322528896</wsa:MessageID>
<wsa:Action>/ChangeConfiguration</wsa:Action>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cs:changeConfigurationRequest>
<cs:key>LaMa_ConnectionRate</cs:key>
<cs:value>5120</cs:value>
</cs:changeConfigurationRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Request in Java :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cs="urn://Ocpp/Cp/2012/06/"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<SOAP-ENV:Header>
<cs:chargeBoxIdentity>Test</cs:chargeBoxIdentity>
<wsa:Action>/ChangeConfiguration</wsa:Action>
<wsa:MessageID>Fake OCPP571322528896</wsa:MessageID>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<cs:changeConfigurationRequest>
<cs:key>LaMa_ConnectionRate</cs:key>
<cs:value>5120</cs:value>
</cs:changeConfigurationRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Fault response to Java :
<?xml version="1.0" encoding="UTF-8"?><env:Envelope
xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header/>
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Sender</env:Value>
</env:Code>
<env:Reason>
<env:Text xml:lang="en-US">XML Request is not well formed!</env:Text>
</env:Reason>
</env:Fault>
</env:Body>
</env:Envelope>
Update :
My Java code should be sending "http://www.w3.org/2003/05/soap-envelope" for "SOAP-ENV", as shown below in my code. However it somehow sends "http://schemas.xmlsoap.org/soap/envelope/" instead. I don't understand why.
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope");

Set SOAP request default values using Spring and Axis2

I don't know if this is even possible, I've been looking around and haven't found anything even related to this... or maybe I'm just not using the right terms to find it.
The problem is this.. let's say I have this request:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://request.dto.webservices.com/xsd">
<soap:Header/>
<soap:Body>
<impl:testServiceMethod>
<xsd1:booleanField1>?</xsd1:booleanField1>
</impl:testServiceMethod>
</soap:Body>
</soap:Envelope>
What's currently happening is that on the back-end side the booleanField1 (which is Boolean), is received as false instead of null. To get the null I have to remove the field from the request.
Is there a way to set anywhere on the code that behavior?

Remove namespace tag in web service response using Spring-WS and Jaxb

I'm using a endpoint SOAP created On Spring Framework using JAXB, but I want that my anwers(Expected Response) return without prefix when I Send Request One, but this is returned like is showed on Current Response:.
How can I do to return a message SOAP without namespaces?
Request One
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
<soapenv:Header/>
<soapenv:Body>
<urn:ZProveerDatosPagoProveed2>
<Bukrs>RG10</Bukrs>
<Langu>S</Langu>
<Lifnr>00000000</Lifnr>
</urn:ZProveerDatosPagoProveed2>
</soapenv:Body>
</soapenv:Envelope>
Current Response:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<n0:ZProveerDatosPagoProveed2Response xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<Adrnr>0000</Adrnr>
<Bankk>0000</Bankk>
<Bankn>0000</Bankn>
<Bkont>0000</Bkont>
<Iban>ES0000</Iban>
<KoinhFi>ROBLES AVN</KoinhFi>
<Land1>TH</Land1>
<Landx>XXXXX</Landx>
<Name1>ROBLES AVN</Name1>
<Pstlz>0000</Pstlz>
<Stcd1>A0000</Stcd1>
<Stras>ROBLES AVN</Stras>
<Swift>XXXXX</Swift>
<Text1_052>ROBLES AVN</Text1_052>
<Zterm>Z000</Zterm>
</n0:ZProveerDatosPagoProveed2Response>
</soap-env:Body>
</soap-env:Envelope>
Request one and the current response, are the request/response of a web service embedded in another web service (which I implemented), the reason for this implementation is that it has requested that the final answer is this (without namespaces tags):
Expected Response
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header/>
<soap-env:Body>
<ZProveerDatosPagoProveed2Response xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
<Adrnr>0000</Adrnr>
<Bankk>0000</Bankk>
<Bankn>0000</Bankn>
<Bkont>0000</Bkont>
<Iban>ES0000</Iban>
<KoinhFi>ROBLES AVN</KoinhFi>
<Land1>TH</Land1>
<Landx>XXXXX</Landx>
<Name1>ROBLES AVN</Name1>
<Pstlz>0000</Pstlz>
<Stcd1>A0000</Stcd1>
<Stras>ROBLES AVN</Stras>
<Swift>XXXXX</Swift>
<Text1_052>ROBLES AVN</Text1_052>
<Zterm>Z000</Zterm>
</ZProveerDatosPagoProveed2Response>
</soap-env:Body>
</soap-env:Envelope>
The way I was able to do it is the following:
Include the two following jars from JAXB : jaxb-core.jar and jaxb-impl.jar
In the package-info.java file, set the following settings:
Supposing your namespace is "yournamespace"
#javax.xml.bind.annotation.XmlSchema(namespace = yournamespace,
xmlns = {#javax.xml.bind.annotation.XmlNs(prefix = "",
namespaceURI = yournamespace)},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNSET)
package com.ctpayment.admin;
It seems that the current implementation of java ignore the previous settings but the jaxb jars do not. I did not push my investigation further. Last but not least, you need the two jars in order to compile.

Handling binary data with SOAP

I have been investigating how to handle binary data with SOAP messages. I am developing both the client and the service so i have the option of choosing whichever framework. The only constraint is that the Service end has already been designed and is based on Spring-WS.
Looking at google, it looks like there are three options:
Sending the attachment inline as base64 in the SOAP message (Base64Binary).
Sending the attachment outside of the SOAP message. i.e. with a reference to the attachement (SWA)
Sending the attachement outside the message but make it appear as though it is embedded in the message (MTOM).
Questions
What exactly does it mean when they say that the attachement is outside of the SOAP message? I assume that maybe the attachement is sent as a different TCP package but i think i am wrong?
Which of the above options is recommended and specifically, which one works best with Spring's Spring-WS framework?
It is unclear to me which of the above options encode the binary content during transmission. What is Binary MIME as described here - http://www.crosschecknet.com/intro_to_mtom.php ? Is the binary data still converted to text during transmission?
What is the format of the data when using SWA?
What exactly does it mean when they say that the attachement is outside of the SOAP message? I assume that maybe the attachement is sent as a different TCP package but i think i am wrong?
In contrast to the first option the attachment is not part of the actual soap message payload but instead referenced to within the SOAP document. The difference between MTOM and SWA is where the referenced file is located. For MTOM it's embedded in the response, while in SWA you could for example get a link to the resource on the web. It follows 3 minimal examples:
MTOM (all in one response of type xop+xml)
Content-type: multipart/related;
type="application/xop+xml";
start-info="text/xml"
--uuid:c73c9ce8-6e02-40ce-9f68-064e18843428
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
Content-Transfer-Encoding: binary
<?xml version="1.0" ?>
<S:Envelope xmlns:S="...">
<S:Body>
<ns2:downloadImageResponse xmlns:ns2="...">
<return>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="cid:012eb00e-9460-407c-b622-1be987fdb2cf#example.jaxws.sun.com">
</xop:Include>
</return>
</ns2:downloadImageResponse>
</S:Body>
</S:Envelope>
--uuid:c73c9ce8-6e02-40ce-9f68-064e18843428
Content-Id: <012eb00e-9460-407c-b622-1be987fdb2cf#example.jaxws.sun.com>
Content-Type: image/png
Content-Transfer-Encoding: binary
SWA (only reference)
Content-Type: application/xml;charset=utf-8;
<?xml version="1.0" ?>
<S:Envelope xmlns:S="...">
<S:Body>
<ns2:downloadImageResponse xmlns:ns2="...">
<return>
https://server.com/downloadImagehere.png
</return>
</ns2:downloadImageResponse>
</S:Body>
</S:Envelope>
Inline
Content-Type: application/xml;charset=utf-8;
<?xml version="1.0" ?>
<S:Envelope xmlns:S="...">
<S:Body>
<ns2:downloadImageResponse xmlns:ns2="...">
<return>
YTM0NZomIz...potentiallyLargeBase64encodedFileGoesInHere...I2OTsmIzM0NTueYQ==
</return>
</ns2:downloadImageResponse>
</S:Body>
</S:Envelope>
Which of the above options is recommended and specifically, which one works best with Spring's Spring-WS framework?
They are all supported, and the one to use depends a bit on your use-case. MTOM seems to be the de-facto standard according to my research. According to me it it's particularly useful if you have either large or multiple file attachements. Since it splits the message in it's logical components it might give the parser more options to handle the binary data efficiently.
However, for smaller data I would probably go for the embedding of the resource, since it's part of the standard SOAP protocol and only uses an encoded byte array directly which is then directly embedded into the message. If portability/compatibility is important this might be the approach to choose.
The last approach obviously requires you to handle the reference by yourself, which might or might not be what you want.
It is unclear to me which of the above options encode the binary content during transmission. What is Binary MIME as described here - http://www.crosschecknet.com/intro_to_mtom.php ? Is the binary data still converted to text during transmission?
MTOM and Inline both encode the file usually as Base64encoded String. For external links it's not relevant.
What is the format of the data when using SWA?
Base64encoded byte array

CXF webservice client, how to handle response from a called webservice?

i have implemented a webservice client that is used inside a webapplication (using Spring) and this client gets a response in which CXF bailsout and gives me an error message.
The error message is:
Server did not recognize the value of HTTP Header SOAPAction
I have found the problem but do not know what i can do to adjust my webservice response handling.
The xml response below works without any problems.
Works and is accepted ok!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bar="http://www.dummyurl.com/service-v1.0/">
<soapenv:Header/>
<soapenv:Body>
<bar:StartSessionResponse>
<result>1</result>
</bar:StartSessionResponse>
</soapenv:Body>
</soapenv:Envelope>
The service actually returns:
Fails and gives me an error!
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<StartSessionResponse xmlns="www.dummyurl.com/service-v1.0/">
<result xmlns="">1</result>
</StartSessionResponse>
</soap:Body>
</soap:Envelope>
The difference as far as i can see is in the placing of the
xmlns="www.dummyurl.com/service-v1.0/ element, in the success xml it is in the enveloppe, in the failed xml it is on the reponse method.
Is there a way that i can convince CXF to accept the response? Or is the service giving back an abnormal result?
The service is giving back a wrong response in the second case, assuming that the first response is proper.
In the first case "www.dummyurl.com/service-v1.0/" is the namespace of your elements - StartSessionResponse, result is not qualified with the namespace. In the second case, the StartSessionResponse has the same namespace as the first sample, but the result has a different namespace altogether, taking out xmlns="" for result will make the xml consistent.

Categories

Resources