Skip to main content
November 19, 2009
Question

Web Service complex datatypes

  • November 19, 2009
  • 2 replies
  • 1822 views

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

This topic has been closed for replies.

2 replies

BKBK
Community Expert
Community Expert
November 20, 2009

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.

Inspiring
November 21, 2009

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.

Inspiring
November 20, 2009

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

November 20, 2009

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


Inspiring
November 20, 2009

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.