When requesting data from my remote server it responds with a value inside a node with the following token , making the parsing process to fail. I manually removed the guilty string and it started working.
<?xml version="1.0" encoding="utf-8"?>
<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>
...
<sFName>Bradley</sFName>
<sLName>Libbra</sLName>
...
Token:
The error raised by Savon is:
Savon::InvalidResponseError: Unable to parse response body:
(aka INFORMATION SEPARATOR TWO) is not an allowed character in XML :
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
Therefore your data is not XML, and any conformant XML processor must report an error such as the one you received.
You must repair the data by removing any illegal characters by treating it as text, not XML, manually or automatically before using it with any XML libraries.
See also How to parse invalid (bad / not well-formed) XML?
My original question was around Savon ruby gem. I sorted this out by changing the default response parser to :rexml. It now parses the invalid character and does not raises an exception.
But right answer would be to parse the malformed XML or ask the provider to fix it. Thanks #kjhughes
Related
I am developing an iPhone app. I have to get data from .NET server. The response is in the following form.
<string xmlns="http://tempuri.org/">
{"success":1,"message":"Data Save Successfully.","returnvalue":"106"}
</string>
I am using NSXMLParser to parse to parse it. I want to get the json string . But the parser is giving error
Server was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.
How can i fix the error.
Thanks in advance
The String in the respons is a JSON, So i think the NSXMLParser don't work with a JSON input. The parsing error is because the syntax of XML is different then from JSON.
This link will help you to read the String JSON response you get.
how to parse json with swift2
I'm building a contract-first SOAP web service with spring-ws 2.2.3. My XML Schema uses extensions, leading to xsi:type= attributes in the XML requests. Since some respones can be very large (30MB), I'm using a AxiomSoapMessageFactory instead of the default SaajSoapMessageFactory, as suggested in the Spring WS docs. I validate incoming requests with a PayloadValidatingInterceptor:
PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
interceptor.setSchema(new ClassPathResource("format-service.xsd"));
interceptor.setValidateRequest(true);
interceptor.setValidateResponse(false);
My problem is that I get spurious validation errors, depending on where in the XML the namespace is declared: if it's declared in the payload, then everything works fine:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<sch:formatRequest xmlns:sch="http://example.com/springws/extension/schema">
<sch:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="sch:currencyType">
<sch:amount>1000</sch:amount>
<sch:currency>EUR</sch:currency>
</sch:value>
</sch:formatRequest>
</soapenv:Body>
</soapenv:Envelope>
But as soon as I move the sch namespace declaration up to the Envelope:
<soapenv:Envelope xmlns:sch="http://example.com/springws/extension/schema" ...>
validation fails and I receive a SOAP Fault:
<faultcode>soapenv:Client</faultcode>
<faultstring xml:lang="en">Validation error</faultstring>
<detail>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-elt.4.1: The value 'sch:currencyType' of attribute 'http://www.w3.org/2001/XMLSchema-instance,type' of element 'sch:value' is not a valid QName.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.2: The type definition cannot be abstract for element sch:value.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-attribute.3: The value 'sch:currencyType' of attribute 'xsi:type' on element 'sch:value' is not valid with respect to its type, 'QName'.</spring-ws:ValidationError>
<spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-complex-type.2.1: Element 'sch:value' must have no character or element information item [children], because the type's content type is empty.</spring-ws:ValidationError>
</detail>
It appears like a bug in the AxiomSoapMessageFactory / Axiom implementation to me (namespace context is lost), as both requests validate fine when using the SaajSoapMessageFactory. Note that the validation only fails on the xsi:type= attribute. The same namespace is recognized correctly for elements.
I cannot use SaajSoapMessageFactory due to high memory consumption for large responses. I found similar problems described in the Spring forum and on SO, but no solution. Thanks for help!
The reason is that Spring-WS uses OMContainer#getXMLStreamReader(). Instead it should use OMContainer#getXMLStreamReader(boolean, OMXMLStreamReaderConfiguration) and set the preserveNamespaceContext property to true in the OMXMLStreamReaderConfiguration object.
You should file a bug for Spring-WS, or even better, fix the issue and submit a pull request.
Trying to call a SAP SOAP Web Service from a generated sudzc app shows errors I don't know:
SudzCExamples[5192:f803] <?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:sap-
com:document:sap:soap:functions:mc-style"><soap:Body><ZComUrlGetrecords>
<IYear>2012</IYear></ZComUrlGetrecords></soap:Body></soap:Envelope>
SudzCExamples[5192:f803] <soap-env:Envelope xmlns:soap-
env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header></soap-env:Header><soap-
env:Body><soap-env:Fault><faultcode>soap-env:Server</faultcode><faultstring
xml:lang="en">CX_ST_MATCH_ELEMENT:XSLT exception.System expected element
'IYear'</faultstring><detail><ns:SystemFault
xmlns:ns="http://www.sap.com/webas/710/soap/runtime/abap/fault/system/">
<Host>undefined</Host><Component>APPL</Component><ChainedException>
<Exception_Name>CX_SOAP_CORE</Exception_Name><Exception_Text>CX_ST_MATCH_ELEMENT:XSLT
exception.System expected element 'IYear'</Exception_Text></ChainedException>
<ChainedException><Exception_Name>CX_SXMLP</Exception_Name><Exception_Text>XSLT
exception</Exception_Text></ChainedException><ChainedException>
<Exception_Name>CX_ST_MATCH_ELEMENT</Exception_Name><Exception_Text>System expected
element 'IYear': Main Program:/1BCDWB/WSS825E06E4DEC40F9171D|
Program:/1BCDWB/WSS825E06E4DEC40F9171D| Line: 18| Valid:X</Exception_Text>
</ChainedException></ns:SystemFault></detail></soap-env:Fault></soap-env:Body></soap-
env:Envelope>
2012-03-11 20:09:30.631 SudzCExamples[5192:f803] soap-env:Server CX_ST_MATCH_ELEMENT:XSLT
exception.System expected element 'IYear'
(null)
The strange thing is that it seems as if the request has the IYear element. Can someone tell me where to search the problem?
I ran into this same problem yesterday and discovered the solution after some experimentation. First thing I did was use my SoapUI client to make the request successfully. SoapUI comes with a free trial and even if you do not use the free trial you can still use it to make accesses to the web service without registering it. I used the xml from the successful request I made to compare against the request that SudzC was making. They differ in several ways, and the way that SudzC forms the request is not sufficient.
My suggestion to you is to compare the two requests and change SudzC's request to match the SoapUI request. You can do this by editing the Soap source code that SudzC gives to you, this source code is found particularly in the Soap.m file in the createEnvelope function.
Also, if your requests have an empty header SudzC does not include the header part of the request. Hard code in an empty header after the namespace portion of the envelope. Doing all this fixed this exact issue for me.
I am attempting to consume a web service using Delphi 2010 and Indy. To establish a usable SOAP stream to compare to the one created by my program, I am testing in SOAPUI. I am using a SOAP stream provided by the web service provider which also matches the SOAP stream specified in the WSDL file. I am getting an HTTP 400 (bad request) error from the service.
From what I can find online, it appears that receiving an HTTP 400 error indicates that your SOAP request is malformed and can not be read by the web service. I have tested my SOAP stream using XMLPad and the XML seems to be well formed. I suppose this may mean that something does not match its schema requirement. I will first check the schema description for the password in case that is expected to not be sent as plain text. What else should I be checking to eliminate an HTTP 400 error?
Here is my request (less username and password) in case it helps:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xop="http://www.w3.org/2004/08/xop/include"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://wwww3.org/2001/XMLSchema-instance">
<soap:Header>
<wsa:Action>http://edd.ca.gov/SendTransmission</wsa:Action>
<wsa:MessageID>urn:uuid:5aa788dc-86e1-448b-b085-2d2743cf9f26</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://fsettestversion.edd.ca.gov/fsetproxy/fsetservice.asmx</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken">
<wsse:Username>#USERNAME#</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#PASSWORD#/wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">O5QWht1bslLCX6KnlEypAA==</wsse:Nonce>
<wsu:Created>2012-02-29T22:32:38.250Z</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="Timestamp-805a7373-335c-43b6-ba21-6596c4848dbf">
<wsu:Created>2012-02-22T15:41:42Z</wsu:Created>
<wsu:Expires>2012-02-22T15:46:42Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<SendTransmission xmlns="http://edd.ca.gov/">
<SendTransmissionRequest xmlns="http://www.irs.gov/a2a/mef/MeFTransmitterServiceWse.xsd">
<TransmissionDataList>
<Count>1</Count>
<TransmissionData>
<TransmissionId>123456789</TransmissionId>
<ElectronicPostmark>2012-02-22T07:41:42.2502206-08:00</ElectronicPostmark>
</TransmissionData>
</TransmissionDataList>
</SendTransmissionRequest>
<fileBytes>
<xop:Include href="cid:1.634654933022658454#example.org"/>
</fileBytes>
</SendTransmission>
</soap:Body>
</soap:Envelope>
There may be something else, but at the moment, I am suspicious of the wsse:UsernameToken. I downloaded the document at http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf and read it last night. It's written in fairly plain language and I feel like I understand what it is saying but it leaves me with a smaller question than the one I asked originally. This document proposes that you can use a plain text password in this format:
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>Zoe</wsse:Username>
<wsse:Password>IloveDogs</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
Or you can use a password digest. It defines a password digest like this:
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
According to the reference, the format for a password digest would look like this:
<S11:Envelope xmlns:S11="..." xmlns:wsse="..." xmlns:wsu= "...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>NNK</wsse:Username>
<wsse:Password Type="...#PasswordDigest">
weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==
</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wsu:Created>2003-07-16T01:24:32Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
This is not the format used in the example provided by the web service publisher. The plain text version in the reference does not use a nonce. The example message uses a nonce but calls for a plain text password. It appears to me that the use of a nonce without a password digest does not add any security to the message. It could be any random string of characters if there is no agreement for how it is to be created. Am I missing the point?
I know this must seem like a tedious undertaking, but I am hoping that by providing this here, maybe we can provide a little help to the next person coming along.
I too have come across this issue. The web service publisher (edd.ca.gov) responded by stating that the " value is required by the SOAP 1.2 standards" yet I find no valid support for that. It looks like we both are heading down the same path (FSET) and maybe we should team up and work together, two heads are better than one. I have found many mistakes within the example code and I too have yet get it to work.
I'm trying to build a web-service, which will receive large files and save them with the name specified in SOAP message.
Here is an example request message
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://mywebservice.com.ua/bait/schemas" xmlns:xm="http://www.w3.org/2005/05/xmlmime">
<soapenv:Header/>
<soapenv:Body>
<sch:SubmitProjectFileRequest>
<sch:ProjectName>MyADProject.xml</sch:ProjectName>
<sch:ProjectFile xm:contentType="text/text">cid:710420383131</sch:ProjectFile>
</sch:SubmitProjectFileRequest>
</soapenv:Body>
</soapenv:Envelope>
I've build some stuff already: I can receive large XOP files without OutOfMemoryError.
The problem is that I can't access ProjectName node of the request, as any attempts to get it lead to inlining of an attachment into request. And that itself leads to OutOfMemoryError
Here is the code which I currently use for that purpose
#PayloadRoot(localPart = SUBMIT_PROJECT_FILE_REQUEST, namespace = NAMESPACE_URI)
public void handleSubmitProjectFileRequest(SoapMessage message) throws Exception {
String projectName = getProjectName(message.getDocument());
Attachment attachment = message.getAttachments().next();
projectFileService.storeProjectFile(projectName, attachment.getDataHandler());
}
private String getProjectName(Document xml) throws XPathExpressionException {
String prefix = xml.lookupPrefix(NAMESPACE_URI);
NodeList names = xml.getElementsByTagName(String.format("%s:%s", prefix, "ProjectName"));
String projectName = names.item(0).getTextContent();
return projectName;
}
Could anyone help me to extract both large XOP attachment and ProjectName node content using Spring WS and Axiom?
Thanks in advance
From what I read (Sorry could only post 2 links total):
http://www.java.net/node/690763
markmail.org/message/utd5ineljlvvugse
And by the detailed definition of the MTOM method:
www.crosschecknet.com/intro_to_mtom.php
Although optimized for transport, the base64 encoded data that you attach to your message will still be unmarshalled and put back into the soap message before a basic handler (Like SOAPHandler for example) gets ahold of it. This seems to be a limitation of this methodology.
Using the technologies you mentioned puts you on the right track for a solution (compared to those of us who were cornered into using basic SOAPMessage and SOAPHandlers). If you use some of the specialized objects in AXIOM and spring, you should be able to accomplish this. CHeck this article out here: http://forum.springsource.org/archive/index.php/t-48343.html
Thanks,
KK