如何在 Coldfusion 中创建复杂类型变量以在 SOAP 请求参数中使用?
更新
在仔细阅读文档后,我注意到我遗漏了 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>
这是 SOAP XML 请求
<?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 包时将它们视为 null。
原文如下
我有一个正在尝试访问的网络服务。问题是 WSDL 定义的方法具有复杂类型参数。实际上,这些复杂类型实际上是非常简单的结构和数组,但我收到错误
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>
UPDATE
After perusing the docs some more I noticed that I left out the FieldArray and PropertyArray keys. So I no longer get the type mismatch error, but the SOAP request is still not right.
Here is the Error
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.... ''
Here is the revised Code
<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>
Here is the SOAP XML request
<?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>
It now appears that despite the contents of the structures I am passing into the request as arguments, they are being considered null by Coldfusion for building the SOAP package.
ORIGINAL BELOW
I have a web service I am trying to access. The problem is that the methods defined by the WSDL have complexType arguments. In reality these complex types are actually quite simple structs and arrays, but I get the error
java.lang.IllegalArgumentException: argument type mismatch
Here is the WSDL link
http://tasks.arcgisonline.com/ArcGIS/services/Locators/TA_Address_NA_10/GeocodeServer?wsdl
Here is some documentation on the service
http://help.arcgis.com/en/arcgisserver/10.0/apis/soap/index.htm#SOAP_Geocode_GeocodeAddresses.htm
Here is the code I am trying to test this with
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是开始使用 Coldfusion 处理复杂数据类型的好地方。它们可能非常棘手,因为您可能需要一个数组、一个结构数组或一个简单结构,具体取决于 WSDL 的项目。
http://tjordahl.blogspot.com/2008/04 /reprint-consuming-web-service-complex.html (不要丢弃它,因为它是旧的 - 该信息仍然是 CF9 的相关事件)
通常,如果有多个项目,您需要创建一个数组,否则它是一个结构体。我发现您需要对结构使用 str['key'] 而不是 str.key 或 str = {key=value} ,因为仅通过第一个约定来维护区分大小写。
根据我的经验,这需要大量的试验和错误,特别是如果您要传递多个项目到请求中。
This is a really good place to get started with consuming complex datatypes with Coldfusion. They can be very tricky since you may need an array, an array of structs or a simple struct depending on item the WSDL.
http://tjordahl.blogspot.com/2008/04/reprint-consuming-web-service-complex.html (don't discard it because it's old - the information is still relevant event for CF9)
Generally, if there is more than one item, you will need to create an array, otherwise it's a struct. I've found you need to user str['key'] rather than str.key or str = {key=value} for structures since case sensitivity is only maintained with the first convention.
In my experience, it takes a lot of trial and error, especially if you have several items you are passing into the request.
您需要使用 CFC 镜像复杂数据类型,请参阅:
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7dbf.html
You need to mirror the complex data type with CFC, see:
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7dbf.html