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

Web Service complex datatypes

Guest
Nov 19, 2009 Nov 19, 2009

Copy link to clipboard

Copied

I'm trying to connect a CFC to a non-CF webservices.  I have the WSDL file, and I can GET all the information I need, but I keep failing on the PUT of information.

the ws.putMarks() funciton takes in a string, a long and a complex data type.  This data type is a custom array-type, which contains custom type objects.  What ever I've tried sending keeps giving me the following error:

"Cannot perform web service invocation putMarks().  The fault returned when invoking the web serivce operation is:

     ' ' java.lan.IllegalArgumentException: argument type mismatch

"

So, I'm stuck. I can't figure out how to create a coldfusion object of the correct datatype.  I tried sending it an array of structures, but that failed.

The portion of the WSDL file that I am using is:

<message name="myMarksInService_putMarks">
     <part name="instructorID" type="xsd:string"/>
      <part name="assessmentId" type="xsd:long"/>
     <part name="marks" type="tns:classAssessmentMarkRemoteArray"/>
</message>

The schema in the WSDL shows:

<xs:complexType final="#all" name="classAssessmentMarkRemoteArray">
     <xs:sequence>
          <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="tns:classAssessmentMarkRemote"/>
     </xs:sequence>
</xs:complexType>

and

<xs:complexType name="classAssessmentMarkRemote">
     <xs:sequence>    
          <xs:element minOccurs="0" name="studentID" type="xs:string"/>
          <xs:element minOccurs="0" name="mark" type="xs:string"/>
          <xs:element minOccurs="0" name="markFeedBack" type="xs:string"/>
     </xs:sequence>
</xs:complexType>

I've hunted everywhere, and can't find out how to create an object in CF of the right type.  Any help the group could offer would be most helpful!

Thanks!

Jenn

TOPICS
Advanced techniques

Views

1.5K

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
Advisor ,
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

Can you post the entire WSDL and the code you have attempted to use?

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
Guest
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

We managed to successfully sent putMarks() the required parameters, but we still cannot create the objects.  What I did was call getMarks(), and then take the results, and put them directly into putMarks().  While this confirms that the WSDL and WS methods work, I still need to be able to create the necessary objects from scratch.  Haveing to getMarks(), empty them out, and then clone the results as many time for adding new marks is clearly not the best solution to this problem.

The WSDL file is attached.  By reques of our administrators, I have removed the acutual domain in the URLs.

I am using the following code to connect to the WS:

<cfscript>
        //create the web service object
        nsid = "usersname";
        password = "anything";
        wsns = "http://www.jboss.org/seam/webservice";
        ws = CreateObject("webservice", "URLtoWSDL");
        ws.setMaintainSession(true);
        ret = ws.login(nsid,password);
        responseHeader = getSOAPResponseHeader(ws,wsns,"conversationId",true);
          //get conversationID from response header
          theHeader = AddSOAPRequestHeader(ws,wsns,"conversationId",#responseHeader#);

       marksList = ws.getMarks("usermame","role","12347");
       marksPut = ws.putMarks("username",1234, marksList);
           ws.logout();
    </cfscript>

As far as trying  to create the object, I hvae tried:

<cfobject type="webservice" action="create" name="marks" webservice="URLtoWSDL">, which gives me an object of type MyMarksInServiceBindingStub.

I need to findout how to create objects of type tns:classAssessmentMarkRemote, and add them to an object of type tns:classAssessmentMarkRemoteArray.  This is what stumps me.

Thanks for any help you may have to offer.


Jenn


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
Advisor ,
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

This looks like the definition for the type classAssessmentMarkRemote

<xs:complexType name="classAssessmentMarkRemote">

<xs:sequence>
<xs:element minOccurs="0" name="bannerId" type="xs:string"/>
<xs:element minOccurs="0" name="mark" type="xs:string"/>
<xs:element minOccurs="0" name="markFeedBack" type="xs:string"/>
</xs:sequence>
</xs:complexType>

Try create a struct for each classAssessmentMarkRemote item and add each struct to an array

<!--- create a classAssessmentMarkRemote item --->
<cfset myMarkItem=StructNew() />
<cfset myMarkItem["bannerId"] = "AN_ID" />
<cfset myMarkItem["mark"] = "A" />
<cfset myMarkItem["markFeedBack"] = "TEST" />


<!--- add item to array --->
<cfset myMarkArray=ArrayNew(1) />
<cfset myMarkArray=ArrayAppend(myMarkArray, myMarkItem) />


<!--- line to invoke putMarks operation --->
ws.putMarks("username",1234, myMarkArray);

Note that none of this code is tested.

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
Guest
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

Well, I have a NEW error now

I tried:

<cfscript>

    arrMarks = StructNew();
    strMark = StructNew();
    strMark.bannerId = "11072914";
    strMark.mark ="77";
    strMark.markFeedBack = "Do Better";
    //ArrayAppend(arrMarks,strMark);
    StructInsert(arrMarks,"item",strMark);

</cfscript>

I tried as an array, but got the type mismatch error again, so we tried as a structure, which gives me the error:

Error converting CFML arguments to Java classes for web service invocation.
Unable to create web service argument class [Lca.myURL.myMarks.action.ClassAssessmentMarkRemote;. Error: java.lang.InstantiationException: [Lca.myURL.myMarks.action.ClassAssessmentMarkRemote;. Often this is because the web service defines an abstract complexType as an input to an operation. You must create an actual instance of this type in Java.

We are at a complete loss at this point.  I did a "getMarks(), and dumped the object I got in return, and this is what it gave me:

object of ca.myURL.myMarks.action.ClassAssessmentMarkRemoteArray
Class Nameca.myURL.myMarks.action.ClassAssessmentMarkRemoteArray
Methods
Method Return Type
equals(java.lang.Object)boolean
getDeserializer(java.lang.String, java.lang.Class, javax.xml.namespace.QName)org.apache.axis.encoding.Deserializer
getItem(int)ca.myURL.myMarks.action.ClassAssessmentMarkRemote
getItem()ca.myURL.myMarks.action.ClassAssessmentMarkRemote[]
getSerializer(java.lang.String, java.lang.Class, javax.xml.namespace.QName)org.apache.axis.encoding.Serializer
getTypeDesc()org.apache.axis.description.TypeDesc
hashCode()int
setItem(ca.myURL.myMarks.action.ClassAssessmentMarkRemote[])void
setItem(int, ca.myURL.myMarks.action.ClassAssessmentMarkRemote)void

What we're going to try next is to create a method in the web service that when I call it, it will return to me an empty object I seem to be unable to create so that I can populate it and send it back.

I don't see why there isn't a simple way to call the remote class to create an object!

Thanks for you help!

Jenn

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
Advisor ,
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

I reviewed the WSDL again. I was mistaken about the type for the type "classAssessmentsRemoteArray". It is not declared as an array. It is zero or more "classAssessmentMarkRemote" items.

Take a look at this blog entry. The sample WSDL uses zero or more "nickname" elements similar to how your WSDL uses "classAssessmentsRemoteArray" containing 0 or "classAssessmentMarkRemote" items.

http://tjordahl.blogspot.com/2008/04/reprint-consuming-web-service-complex.html

You might also try using the wsdl2java tool to look at the Java types created for the WSDL.

http://go.adobe.com/kb/ts_eaf0396_en-us

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
Guest
Nov 24, 2009 Nov 24, 2009

Copy link to clipboard

Copied

LATEST

The first link you listed had the answer for me once I dug into the post.

What I had to do was:

<cfscript>
    arrMarks = structNew();
    arrMarks.item = ArrayNew(1);
    arrMarks.item[1] = StructNew();
    arrMarks.item[1].bannerId = "nks457it's ";
    arrMarks.item[1].mark ="77";
    arrMarks.item[1].markFeedBack = "Do Better";
 
</cfscript>

And then when I called the component, I passed in arrMarks.  In the component function, I took in the argument, but did not type it.

What a confusing way to do things, but its now working, so I'm happy.

Thank you for all your help!

Jenn

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
Community Expert ,
Nov 20, 2009 Nov 20, 2009

Copy link to clipboard

Copied

What about cfproperty ? Something like this:

Save the following code as classAssessmentMarkRemote.cfc

<cfcomponent>
   <cfproperty name="studentID" type="string" default="a1b2c3">
   <cfproperty name="mark" type="string" default="80">
   <cfproperty name="markFeedBack" type="string" default="Keep it up">
</cfcomponent>

Then pass an instance of the cfc in the web service method.

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
Advocate ,
Nov 21, 2009 Nov 21, 2009

Copy link to clipboard

Copied

BKBK is right. What you webservice needs as arguments are the instructorID, the assesmentId and an array of hisclassAssessmentMarkRemote.cfc, objects.

Webservices are typed. CFML is not. To make something typed in CF, you need an instance of a CFC with its properties defined using cfproperty.

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