• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Complex data type help sought

New Here ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

Hi All,

This seems like it should be simpler than it has been for me, but I am neither an expert with webservices nor CF. Though not a newbie, my guess is that there is something fundamental I am missing. I have sought answers to this and read many articles, but either the suggestions do not work, do not apply or talk of writing a wrapper in java. Perhaps it isn't even possible to represent this in CF, but I have not seen anything that says that, either.

Anyway, the webservice I call returns an array of objects named TABLE_OF_BAPIRET2 (if I am understanding properly. After making the call, doing a cfdump of the result I get Variable TABLE_OF_BAPIRET2 is undefined. See attached code below.

This is not surprising after reading Handling complex data types. So, I changed the cfdump to reference TABLE_OF_BAPIRET2.MESSAGE. This did not work (I did not expect it to since there is nothing in the statement referencing the array element). However, it did give me more promising results: Element MESSAGE is undefined in TABLE_OF_BAPIRET2. This tells me I can reference the return variable as suggested by the cited article, but I must be doing something wrong. NOTE: when I specified an index by stating TABLE_OF_BAPIRET2[1].MESSAGE, I go back to the error Variable TABLE_OF_BAPIRET2 is undefined. This I did not expect and am now stumped.

I've attached below the relevant section of the wsdl defining the structure. I am also attaching the SOAP message that is returned.

Is it even possible to decipher this object? Or, do I need to use java (I am comfortable with that, but would rather use CF). I strongly believe this is not the case, that there is something fairly simple I am overlooking, but cannot see it. So, any help is greatly appreciated!

TIA,

bill
TOPICS
Advanced techniques

Views

2.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

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?

bill

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

wltiii wrote:
> I did, BTW, try to use returnVariable="TABLE_OF_BAPIRET2[]" as is
> suggest by the article
> http://www.coldfusionjedi.com/index.cfm?mode=entry&entry=FAE8F3B9-BC72-0C47-D669
> 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?
>
> bill
>

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

quote:

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.

quote:

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:

quote:

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.


(Emphasis mine).

quote:

If you put the webservice URL in a browser do you get the correct WSDL file?


Yes.

quote:

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).

quote:

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

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
interior elements.

So does the <cfdump var="#Table_of_Bapiret2#"> show something on the
screen or does it throw an 'undefined' error?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

quote:

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.

quote:

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 20, 2008 Feb 20, 2008

Copy link to clipboard

Copied

What happens with this code.

<cfset ws =
createObject("webservice"," http://sapcrd.comfort.com:8000/sap/bc/srt/rfc/sap/Z_YXG_SIMPLE_IN
PUT_TEST_WS?sap-client=300&wsdl=1.1")>

<cfdump var="#ws#">

P.S. My day is done in about 45 minutes. I'll see any responses after
that time tomorrow.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 23, 2008 Feb 23, 2008

Copy link to clipboard

Copied

quote:


wltiii wrote:
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

<cfoutput>#NonExistantStruct.Message#</cfoutput>

Element MESSAGE is undefined in NONEXISTANTSTRUCT.

So in this case I would believe what IsDefined is reporting ie. the object does not exist.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 25, 2008 Feb 25, 2008

Copy link to clipboard

Copied

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 :-)

bill

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 25, 2008 Feb 25, 2008

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 25, 2008 Feb 25, 2008

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

wltiii,

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.

AddSOAPResponseHeader
GetSOAPResponse
GetSOAPResponseHeader

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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. :-(



Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

wltiii wrote:
> -------------------------------------------------
> my soap response
> -------------------------------------------------
> <soap-env:Envelope xmlns:soap-env=" http://schemas.xmlsoap.org/soap/envelope/">
> <soap-env:Body>
> <n0:Z_YXG_SIMPLE_INPUT_TESTResponse
> xmlns:n0="urn:sap-com:document:sap:rfc:functions">
> <BAPIRET2>
> <item>
> <TYPE>S</TYPE>
> <ID>Trillium</ID>
> <NUMBER>001</NUMBER>
> <MESSAGE>This is a test.</MESSAGE>
> <LOG_NO/>
> <LOG_MSG_NO>000000</LOG_MSG_NO>
> <MESSAGE_V1/>
> <MESSAGE_V2/>
> <MESSAGE_V3/>
> <MESSAGE_V4/>
> <PARAMETER/>
> <ROW>0</ROW>
> <FIELD/>
> <SYSTEM/>
> </item>
> <item>
> <TYPE>S</TYPE>
> <ID>Trillium</ID>
> <NUMBER>002</NUMBER>
> <MESSAGE>This is a test.</MESSAGE>
> <LOG_NO/>
> <LOG_MSG_NO>000000</LOG_MSG_NO>
> <MESSAGE_V1/>
> <MESSAGE_V2/>
> <MESSAGE_V3/>
> <MESSAGE_V4/>
> <PARAMETER/>
> <ROW>0</ROW>
> <FIELD/>
> <SYSTEM/>
> </item>
> </BAPIRET2>
> </n0:Z_YXG_SIMPLE_INPUT_TESTResponse>
> </soap-env:Body>
> </soap-env:Envelope>
>

Which dump produced this output? 'Req', 'Resp' or 'OUT'?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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);
2) <cfscript>this.DebugLog.logEvent(#XMLText#);</cfscript>

The updated code is shown attached. It is the call to the logger that produced this output (line 2 above).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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[1] 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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

wltiii,

Try the tip here.

...
<cfset result = XmlSearch(mydoc, "//*[local-name()='item']/")>
<cfdump var="#result#">

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

wltiii,

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 26, 2008 Feb 26, 2008

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 27, 2008 Feb 27, 2008

Copy link to clipboard

Copied

wltiii wrote:
> 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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 27, 2008 Feb 27, 2008

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Feb 27, 2008 Feb 27, 2008

Copy link to clipboard

Copied

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.

bill

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Feb 27, 2008 Feb 27, 2008

Copy link to clipboard

Copied

wltiii wrote:
> 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
somewhere public?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation