Как создать переменные complexType в Coldfusion для использования в аргументах запроса SOAP? - PullRequest
1 голос
/ 16 августа 2011

UPDATE


После просмотра документов я заметил, что пропустил ключи FieldArray и PropertyArray. Поэтому я больше не получаю ошибку несоответствия типов, но запрос SOAP все еще не верен.

Вот ошибка

The fault returned when invoking the web service operation is:
AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}client faultSubcode: faultString: Error processing server request faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}stackTrace:Error processing server request at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:221) at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:128) at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087) at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.... ''

Вот пересмотренный код

<cfscript>
function newField(Name, Type, IsNullable, Length, Precision, Scale) {
    s=StructNew();
    s["Name"]=arguments.Name;
    s["Type"]=arguments.Type;
    s["IsNullable"]=arguments.IsNullable;
    s["Length"]=arguments.Length;
    s["Precision"]=arguments.Precision;
    s["Scale"]=arguments.Scale;
    return s;
}

function newRecord(oid, zipcode) {
    a=ArrayNew(1);
    ArrayAppend(a, arguments.oid);
    ArrayAppend(a, arguments.zipcode);
    return a;
}

function newKeyValue(key, value) {
    s=StructNew();
    s["Key"]=arguments.key;
    s["Value"]=arguments.value;
    return s;
}
</cfscript>


<cftry>

<cfscript>
ws = CreateObject("webservice", "http://tasks.arcgisonline.com/ArcGIS/services/Locators/TA_Address_NA_10/GeocodeServer?wsdl");
recordset=StructNew();
</cfscript>

<h1>GeocodeAddresses</h1>
<cfscript>
fields=StructNew();
fields["FieldArray"]=ArrayNew(1);
ArrayAppend(fields.FieldArray, newField("oid", "esriFieldTypeOID", false, 10, 0, 0));
ArrayAppend(fields.FieldArray, newField("zipcode", "esriFieldTypeString", true, 10, 0, 0));
recordset["Fields"]=fields;

records=ArrayNew(1);
ArrayAppend(records, newRecord(1,"33607"));
ArrayAppend(records, newRecord(2,"90210"));
recordset["Records"]=records;


mappings=StructNew();
mappings["PropertyArray"]=ArrayNew(1);
ArrayAppend(mappings.PropertyArray, newKeyValue("oid", "oid"));
ArrayAppend(mappings.PropertyArray, newKeyValue("Zip", "zipcode"));

propertys=StructNew();
propertys["PropertyArray"]=ArrayNew(1);
</cfscript>

<cfscript>
result = ws.geocodeAddresses(AddressTable=recordSet, AddressFieldMapping=mappings, PropMods=JavaCast("null", ""));
</cfscript>

<cfdump var="#ws#" label="#GetCurrentTemplatePath()#" />

<cfcatch>
    <cfdump var="#cfcatch#" label="#GetCurrentTemplatePath()#" />
    <cfdump var="#GetSOAPRequest(ws)#" label="#GetCurrentTemplatePath()#" />
    <cfdump var="#GetSOAPResponse(ws)#" label="#GetCurrentTemplatePath()#" />
</cfcatch>
</cftry>

Вот XML-запрос SOAP

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <GeocodeAddresses xmlns="http://www.esri.com/schemas/ArcGIS/10.0">
            <AddressTable xmlns="" xsi:nil="true"/>
            <AddressFieldMapping xmlns="" xsi:nil="true"/>
            <PropMods xmlns="" xsi:nil="true"/>
        </GeocodeAddresses>
    </soapenv:Body>
</soapenv:Envelope>

Теперь кажется, что, несмотря на содержимое структур, которые я передаю в запрос в качестве аргументов, Coldfusion считает их нулевыми для построения пакета SOAP.


ОРИГИНАЛ НИЖЕ


У меня есть веб-сервис, к которому я пытаюсь получить доступ. Проблема заключается в том, что методы, определенные WSDL, имеют аргументы complexType. На самом деле эти сложные типы на самом деле являются довольно простыми структурами и массивами, но я получаю ошибку

java.lang.IllegalArgumentException: argument type mismatch

Вот ссылка WSDL
http://tasks.arcgisonline.com/ArcGIS/services/Locators/TA_Address_NA_10/GeocodeServer?wsdl

Вот некоторая документация по сервису
http://help.arcgis.com/en/arcgisserver/10.0/apis/soap/index.htm#SOAP_Geocode_GeocodeAddresses.htm

Вот код, который я пытаюсь проверить с помощью

<cfscript>
function newField(Name, Type, IsNullable, Length, Precision, Scale) {
    s=StructNew();
    i=0;
    for(i in arguments){
        s[i]=arguments[i];
    }
    return s;
}

function newRecord(oid, zipcode) {
    a=ArrayNew(1);
    ArrayAppend(a, arguments.oid);
    ArrayAppend(a, arguments.zipcode);
    return a;
}

function newKeyValue(key, value) {
    s=StructNew();
    s["Key"]=arguments.key;
    s["Value"]=arguments.value;
    return s;
}
</cfscript>


<cftry>

<cfscript>
ws = CreateObject("webservice", "http://tasks.arcgisonline.com/ArcGIS/services/Locators/TA_Address_NA_10/GeocodeServer?wsdl");
recordset=StructNew();
</cfscript>
<cfdump var="#ws#" label="#GetCurrentTemplatePath()#" />

<h1>GeocodeAddresses</h1>
<cfscript>
fields=ArrayNew(1);
ArrayAppend(fields, newField("zipcode", "esriFieldTypeString", true, 10, 0, 0));
ArrayAppend(fields, newField("oid", "esriFieldTypeOID", false, 10, 0, 0));
recordset["Fields"]=fields;

records=ArrayNew(1);
ArrayAppend(records, newRecord(1,"90210"));
recordset["Records"]=records;


mappings=ArrayNew(1);
ArrayAppend(mappings, newKeyValue("zipcode", "Zip"));
</cfscript>

<cfdump var="#recordSet#" label="#GetCurrentTemplatePath()#" />
<cfdump var="#mappings#" label="#GetCurrentTemplatePath()#" />

<cfscript>
result = ws.geocodeAddresses(recordSet, mappings, JavaCast("null", ""));
</cfscript>

<cfdump var="#ws#" label="#GetCurrentTemplatePath()#" />

<cfcatch>
    <cfdump var="#cfcatch#" label="#GetCurrentTemplatePath()#" />
</cfcatch>
</cftry>

Ответы [ 2 ]

1 голос
/ 16 августа 2011

Это действительно хорошее место для начала использования сложных типов данных с Coldfusion.Они могут быть очень хитрыми, поскольку вам может понадобиться массив, массив структур или простая структура в зависимости от элемента WSDL.

http://tjordahl.blogspot.com/2008/04/reprint-consuming-web-service-complex.html (не выбрасывайте его, потому что он старый - информациявсе еще актуально событие для CF9)

Как правило, если существует более одного элемента, вам нужно будет создать массив, в противном случае это структура.Я обнаружил, что для структур необходимо использовать str ['key'], а не str.key или str = {key = value}, поскольку чувствительность к регистру поддерживается только в первом соглашении.

По моему опыту, это требует много проб и ошибок, особенно если у вас есть несколько элементов, которые вы передаете в запрос.

0 голосов
/ 16 августа 2011

Вам необходимо отразить сложный тип данных с помощью CFC, см .:

http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7dbf.html

...