This content has been marked as final. Show 31 replies
I did, BTW, try to use returnVariable="TABLE_OF_BAPIRET2" as is suggest by the article Did you know: Array of components. That, too, errored, but for a different reason. The error states The string "TABLE_OF_BAPIRET2" is not a valid ColdFusion variable name.
Any pointers or suggestions?
> I did, BTW, try to use returnVariable="TABLE_OF_BAPIRET2" as is
> suggest by the article
> E522B0559213. That, too, errored, but for a different reason. The error states
> The string "TABLE_OF_BAPIRET2" is not a valid ColdFusion variable name.
> Any pointers or suggestions?
That post is meant to talk about the Web Service creation side not the
consumption side. On the consumption side, '' are illegal characters
in a variable name.
You original code should have produced something if something is being
returned by the web service.
If you put the webservice URL in a browser do you get the correct WSDL file?
Where did you capture the SOAP response?
Are you sure something is being sent and received. Can you use tools to
spy on the actual requests and responses?
That post is meant to talk about the Web Service creation side not the consumption side.
Really? I didn't see anything in the article that suggested that, and since it specifically was speaking of returnType, I thought it might work. However, the article does seem to be only about returns from components. I am assuming you are referring to the Did You Know: Arrays of Components article posted at coldfusionjedi.
You original code should have produced something if something is being returned by the web service
I would've thought so, but that does not seem to be the case, and the article "Handling Complex Data Types", in the section talking specifically about consuming a service, suggests otherwise:
You access elements of the variable myReturnVar using dot notation in the same way that you access structure fields. If a complex type has nested elements, in the way a structure can have multiple levels of nested fields, you use dot notation to access the nested elements, as in a.b.c.d, to whatever nesting level is necessary.
However, the variable myReturnVar is not a ColdFusion structure . It is a container for the complex type, but has none of the attributes of a ColdFusion structure. Calling the ColdFusion function isStruct on the variable returns False.
If you put the webservice URL in a browser do you get the correct WSDL file?
Where did you capture the SOAP response?
The host developer has a tool. Sorry, I don't know the name. He was able to capture both the SOAP request and response. He did so when he ran a java version, and again when I ran my CF version. The SOAP response looks exactly as expected (the same when called by both java and CF).
Are you sure something is being sent and received. Can you use tools to spy on the actual requests and responses?
By capturing the SOAP response, I am sure the request must have been received by the service. Since there are no errors unless I try to reference the returnVar, it appears that the response must have been received. I answered about the tools above. Considering that under the condition that I am using dot notation and getting the error that the element MESSAGE is undefined strongly indicates that I do have an object of some sort, just not properly parsing it.
Ok lets be clear here. Are you getting NO response or that the response
is not the complex variable you are expecting.
Looking at the soap response you maybe just getting a XML packet that CF
is treating as a string at this point. Until this XML is processed into
an XML structure you would not be able to use dot notation to access
So does the <cfdump var="#Table_of_Bapiret2#"> show something on the
screen or does it throw an 'undefined' error?
So does the <cfdump var="#Table_of_Bapiret2#"> show something on the screen or does it throw an 'undefined' error?
The statement <cfdump var="#TABLE_OF_BAPIRET2#" /> throws the error Variable TABLE_OF_BAPIRET2 is undefined.
Looking at the soap response you maybe just getting a XML packet that CF is treating as a string at this point. Until this XML is processed into an XML structure you would not be able to use dot notation to access interior elements
This sounds like a promising avenue. However, I just ran the again with the attached code and the isDefined returns NO. I am confused.
What happens with this code.
<cfset ws =
P.S. My day is done in about 45 minutes. I'll see any responses after
that time tomorrow.
Considering that under the condition that I am using dot notation and getting the error that the element MESSAGE is undefined strongly indicates that I do have an object of some sort, just not properly parsing it.
To interject for a moment: Not neccessarily. CF would return that same error if the object does not exist. For example, you would get the same message from this single line of code
Element MESSAGE is undefined in NONEXISTANTSTRUCT.
So in this case I would believe what IsDefined is reporting ie. the object does not exist.
Point taken. However, I still believe something must be coming back for a few reasons.
First and foremost is that we did capture the SOAP response, so unless something happened between the transmission and the reception of the response that has gone undetected, or unless CF rejected the response without throwing any type of error, then I believe I must be getting a response.
Second, the documentation cited earlier, Handling complex data types , states that it is not a CF structure, rather it is a container. It also states that isStruct will return false. I inferred from the quoted section of documentation that CF does not really recognize the returned object, except through explicit reference to the elements contained therein.
Third, I had at one pointed created a var <cfset TABLE_OF_BAPIRET2 = "" /> prior to the invoke, dumped it, then invoked, then dumped again, whereupon the var did not exist. So, something happened to destroy the var. What, I don't know.
Obviously, some of what I state above will expose gaps in my CF knowledge. Be gentle :-)
I would try that, but I cannot figure out how to specify the user and pw in the call as I can with CFINVOKE.
I work with this client only Mon/Tue/Wed, so your leaving in 45 minutes really is not issue. In fact, your effort at helping me solve this is truly appreciated. It wouldn't be very politic of me to rise to anger for your working a normal day rather than spending all your time helping me! Actually, I would have probably been back to this sooner, but am also in crunch mode with my other client, plus I bought a house that I am having remodeled and at the same time trying to move into, as well as working on some of the stuff to complete the remodeling more quickly (painting, flooring, etc.), so I've had no extra time available for this project, just what I must put into it.
Oh, and one more thing makes me believe that something is being returned. The host developer had created a very simple service that took a string and returned a string. I had no problem with that. Unfortunately, because of complexities in his environment, in order to become somewhat more complex, he had to become quite a bit complex. No middle ground, sadly. But, because the simple service worked, and because this service works from a java call, I have no reason to believe that nothing is being returned.
I do not know for certain whether anything is being returned or not. Just that according to ColdFusion if it is receiving a response, it is somehow not being properly being converted into an object you can use. As evidenced by the fact that your return variable is undefined. Though "no response" would seem to be a more likely cause.
You can add or retrieve soap headers using some of the built in soap functions.
So what happens if you try Ian Skinner's code above? You can use AddSOAPResponseHeader to add the username and password and also GetSOAPResponse/Header to view the response?
I've attached the code I ran below (url, user/pw hidden). The first two dumps show the request and response, and they appear as I expect. The third, however, the one containing the result, still gives me an undefined error. I've also attached the SOAP response. NOTE: the integer 2 in the request determines how many rows are returned within BAPIRET2.
So, again, it looks like I am just not interpreting this response properly. You would think it would be simple enough to parse an array of structures. :-(
> my soap response
> <soap-env:Envelope xmlns:soap-env=" http://schemas.xmlsoap.org/soap/envelope/">
> <MESSAGE>This is a test.</MESSAGE>
> <MESSAGE>This is a test.</MESSAGE>
Which dump produced this output? 'Req', 'Resp' or 'OUT'?
This is the SOAP RESPONSE. What you are actually seeing is a result of a couple other statements that I added that I copied and pasted, but this shows all the same values as in the CFDUMP of the response. Specifically the lines added were:
1) XMLText = ToString(resp);
The updated code is shown attached. It is the call to the logger that produced this output (line 2 above).
As you have noted, you are definitely sending and receiving requests and
responses. I do not know why you are having difficulty after this
point. I do know I have used web services where I needed to send and
receive complex data types and it does work.
Can you precess the 'resp' variable to get what you want? Is it a
string or an XML structure?
It is an xml struct, apparently, at least the function IsXml returns YES. I have been trying for hours, with no luck, at parsing the response, however. The SOAP response, of course, is the same as shown before. So, perhaps, you can spot something in my code that prevents my being able to successfully use the XmlSearch function, or to properly display results, or whatever it is I am doing wrong. I've attached my latest code (a snippet of what has been previously shown), and the results. The TYPE should have two occurrences, as far as I can see. So, the having the results from the CFDUMP state array [empty] is confusing. Being empty, that explains why the reference to type returns The element at position 1 cannot be found. I just don't understand why it should be empty. Something wrong with my search? Something wrong with my subsequent reference to type?
> my code snippet
> OUT = ws.Z_YXG_SIMPLE_INPUT_TEST(#myArray#, 2, "This is a test.");
> req = getSOAPRequest(ws);
> resp = getSOAPResponse(ws);
> XMLText = ToString(resp);
> <cfset mydoc = XmlParse(XMLText)>
The above line should be redundant. I.E. turning an XML structure into
a string then parsing that string into an XML structure seems
unnecessary to me. You should try just using 'resp' everywhere you use
'mydoc' in the following code.
> <cfset type = XmlSearch(mydoc,
You might try a simpler search and not worry about all the intermediate
layers. Try <cfset type = XMLSearch(mydoc,'//item')>
> <cfdump var="#type#">
> <br>Is it well formed XML text? #IsXML(XMLText)#
You should also be able to just access the xml structure directly.
Another line of code to play with:
If I've mistyped a layer in there, you may start at a higher point and
work your way done the node tree.
You may notice the choice of bracket "array" notation over dot notation.
When you have complex node names such as this SOAP response there are
illegal characters that disallow the use of dot notation. Array
notation allows one to access these types of XML nodes.
Again my day is done at ~3:30pm US Pacific Time. I will probably see
any response tomorrow. Good Luck until then.
Okay! Great! I accessed the TYPE element! I am sure I can now get to all the elements in the structure. Thanks so much for all of your help!
For those that are reading this now or in the future, a snippet from the final bits of code are attached. I probably do not need to create the mydoc var and could just use var resp instead, but have not tried that.
FWIW - I think having to parse the SOAP response is a horrible kludge. If I had just written the java code after running WSDL2java, it would have taken me far less time. However, I am stubborn and wanted to make CF do what it is supposed to do. Being that this is just a test web service, we'll have to see how well the solution works for me going forward. Ultimately, however, I would really like to know how to parse returnVariable.
yes, I know the conversion to mydoc was unnecessary. that is legacy code from one of the many attempts i made at trying to find a solution.
i tried the bracket notation at some point and it did not work. perhaps i miskeyed something. i will give that another shot.
again, i appreciate the feedback :-)
Try Ian Skinner's suggestion too. XMLSearch(mydoc, "//item") may work as well.
I am still curious about this too. Do you have a public WSDL of this simple test by any chance?
Yes, I thought I would try that form of search as well.
I haven't worked with CF for about 2 years prior to the end of this January, then only for 9 months or so, and not before that since 2000 (a lot changed between those two times!), and then I was leading, not doing much coding, for about a little over a year. For someone with years of experience in many other languages (much more than I would care to admit! hahahaha!), it has been very easy to get into complex tasks quickly. Sadly, it means I have not always been exposed to some of the more obvious things, or I've forgotten what I was exposed to (because of the gaps in using CF mostly). The "relative" form of search was something that I knew must exist, but I had not come across it again. Once I saw Ian's response, I knew I had seen it the last time I was writing CF.
> Once I saw Ian's response, I knew I had seen it the last time I was
> writing CF.
To be fair that is XML XPath syntax not ColdFusion syntax other then
that ColdFusion uses XPath for this purpose.
I just want to clarify that this is not the 'normal' way to consume a
web service. Your first examples is what I would have expected to work.
Why they did not is a mystery. This was a way to get around the
unknown issue and get you access to your results.
As cfSearching asked, I would be curious to see the WSDL for this
exchange. This is stretching my solid knowledge of web services and how
it all fits together, but my assumption is that for CF to auto-magically
parse the SOAP response and return the desired complex data, the WSDL
would have to tell it how to do this.
The solution we cobbled together over the last couple of days, in
effect, bypasses the WSDL. Instead you are decoding the SOAP response
manually. My wild eyed guess is that the WSDL may not properly tell CF
how to decode the SOAP response and that is why you where not getting a
result with the simpler code.
I may have seen that syntax in contexts other than CF development, then, such as java. I have not done much with web services in any environment, but did do some support of existing web service functions in a java environment for nearly two years starting midway through 2003.
I understand that this is a work around, a kludge. I would like to know why I have been unable to process the returnvar, and because there is a little slack right now in the project, I can play with this some more. So, feel free to toss out other suggestions. Because we did find a work around, it gave me other ideas to try, which I will do so today. But, as always, this window of slack time will close quickly.
Since you are both interested in the wsdl, I am attaching the complete wsdl here. I don't know how much that will help. FWIW, the WSDL2Java tool (using the jars installed with CF) seemed to work fine (I never ended up testing the java option, however, since it seemed we were making a lot of progress staying purely in CF). Unfortunately, I cannot expose access to the service to the public.
Okay, here are some interesting results that may provide more input. See attached code. When CF tried to execute the CFDUMP with the label result of bracket array view 5, I received the error coldfusion.runtime.UndefinedElementException: Element SOAP-ENV:Envelope is undefined in a Java object of type class coldfusion.xml.XmlNodeList referenced as . Note the incomplete statement. I have also tried this by dropping the reference to item and going directly to TYPE. That produced the same results. It is interesting, though, that the relative search for item did work (both versions, which I expected). Nothing jumps out at me as to why dump 4 works and dump 5 does not.
> Nothing jumps out at me as to why dump 4 works and
> dump 5 does not.
What does dump 4 actually show? Can you provide a copy or picture of it
it may take a couple days to publish. i am moving from one residence to another, still packing, remodeling the new place, painting, etc., movers are showing up friday, so i have not spent any time trying to get my network up and running. due to size restrictions, i cannot attach the html code here, even though i have tried to remove extraneous bit of information and code. i don't know where i'd publish a photo. however, i've attached a snippet here that may provide enough info for you. of course, you'll have to copy and paste it somewhere to view it. if you want me to publish the whole page, let me know. FWIW - i don't know where i'd publish the photo.
<cfdump label="result of bracket array view 4"
<cfdump label="result of bracket array view 5"
When I looked closer at these two examples there is a very subtle
difference between the two. The case of elements. In view 4 you have
'soap-env' in view 5 you have 'SOAP-ENV'. You may be dealing with one
of the few places where case matters in ColdFusion. I know the standard
indicates that XML is case sensitive, but CF usually is not. Maybe in
this situation, it is.
Good catch! That made the difference. Now all the dumps show what I expect.
Confusingly, though, the following three searches work, and the fourth does not (as evidenced by an empty arry when dumping type[/]), yet, the dump (view 6) that follows that does work. I went back to this to make sure the capitalization was consistent. I know, I've left off the namespace indicator to Z_YXG_SIMPLE_INPUT_TESTResponse, the reason being is that by specifying it the exception message Prefix must resolve to a namespace: n0 was thrown.
> I've left off the namespace indicator to
> Z_YXG_SIMPLE_INPUT_TESTResponse, the reason being is that by specifying
> it the exception message Prefix must resolve to a namespace: n0 was
That made me wonder. I went back to the WSDL you provided and I did not
see any name space defined for 'n0'. I wonder if that means anything?
Could this be the source of the problem that the original code did not
work because CF could not resolve elements in the SOAP response with a
'n0' name space?
I don't know enough about name spaces, XML, WSDL, SOAP and web service
to say if this matters or not.
neither do i, unfortunately. i'll run this past some others to see if they have any idea.