在 ColdFusion 中传递 Java 对象
Passing Java Object in ColdFusion
这是这个问题的延续:WCF and ColdFusion
因此,我设法使用 Metro 和导入 WSDL 获得了一个 JAR。我的主要 class 具有以下功能:getVersion()
和我的实现 myVersion()
、cancelOrder()
和 myCancel()
,最后是 placeOrder
和 myOrder()
.
对于前两种方法(getVersion
和 cancelOrder
),我能够传递正确的信息并从 Web 服务获得响应:
比如在myVersion
方法中调用webservice,输出版本号加上传入的字符串:
<cfset var.myVersion = createObject("java", "com.USOrlando").myVersion(
javaCast("string", "Batman")
)>
<!---Output is [version number] + "I'm Batman" --->
使用相同的模板,我还可以在 myOrder
方法中传递所有其他参数,除了类型为 org.tempuri.ArrayOfSmartOrderLineRequest
.
的最后一个参数
这是我不自信的地方,可能需要指导:
在浏览文档和生成的 classes 时,我会将文档中的内容放在块引号中以及我对它们的理解。
myOrder
应该获取通过 ColdFusion 传入的所有参数并将其放入 request
对象中。
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
JavaCast("org.tempuri.ArrayOfSmartOrderLineRequest", orderItems)
)>
最后一行 JavaCast("org.tempuri.ArrayOfSmartOrderLineRequest", orderItems)
是我的问题。我得到一个
JavaCast type org.tempuri.ArrayOfSmartOrderLineRequest must be one of
the following types: byte, char, short, int, long, float, double,
boolean, string, bigdecimal, their corresponding array representation
(eg : int[]), or null.
错误,有道理。如果我将其设为 null
,则不会向 SoapMessage 传递任何内容。
我的问题是:如何传递最后一个参数?
orderItems
是一个 CF 变量,我相信它引用了一个 Java 对象。
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PluSalesProgramId = myItem.setPLU(1)>
<cfset myItem.PLU = myItem.setPLU("123456")>
<cfset myItem.Quantity = myItem.setPLU(1)>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
逆向计算,ArrayOfSmartOrderLineRequest.java
有一个方法 getSmartOrderLineRequest
。根据生成的 java 文件中的注释:
This accessor method returns a reference to the live list, not a
snapshot. Therefore any modification you make to the returned list
will be present inside the JAXB object. This is why there is not a
set
method for the smartOrderLineRequest property. It continues on
to: For example, to add a new item, do as follows:
getSmartOrderLineRequest().add(newItem);
我认为这意味着我必须创建一个 newItem
对象并将其传递给 getSmartOrderLineRequest
的 add
方法,对吗?因此,在构建 newItem
对象时,我创建了 myItem
变量,它具有三个属性:PLU
、PluSalesProgramId
和 Quantity
.
在我的脑海中,我正在CF中创建一个myItem
对象,它被保存在Java中,然后告诉Java方法getSmartOrderLineRequest
"Hey, ADD myItem
to your array."
如有任何帮助,我们将不胜感激。我觉得我快到了,但我不知道我应该朝哪个方向前进。
编辑 1: 对 Leigh 评论的回应。
当我单独传递对象时会发生什么,这不是一个愚蠢的问题。我重新创建了以下步骤,但出现了一个奇怪的错误:起初,我尝试了以下操作:
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PluSalesProgramId = myItem.PluSalesProgramId(JavaCast("int", "1"))>
<cfset myItem.PLU = myItem.setPLU(JavaCast("string", "123456"))>
<cfset myItem.Quantity = myItem.setPLU(JavaCast("int", "1"))>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
<!---Errors out on myItem.Quantity --->
我试过下面的代码,没有报错:
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PLU = myItem.setPLU(JavaCast("string", "123456"))>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
<!---Errors out on myItem.Quantity --->
我使用以下方式传递它:
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
orderItems
)>
<!---Returned Method Not Found error --->
下面是ArrayOfSmartOrderLineRequest.java的shell:
public class ArrayOfSmartOrderLineRequest {
@XmlElement(name = "SmartOrderLineRequest", nillable = true)
protected List<SmartOrderLineRequest> smartOrderLineRequest;
public List<SmartOrderLineRequest> getSmartOrderLineRequest() {
if (smartOrderLineRequest == null) {
smartOrderLineRequest = new ArrayList<SmartOrderLineRequest>();
}
return this.smartOrderLineRequest;
}
}
以下是 WSDL 中对象的定义:
<xs:complexType name="ArrayOfSmartOrderLineRequest">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="SmartOrderLineRequest" nillable="true" type="tns:SmartOrderLineRequest"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SmartOrderLineRequest">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="PluSalesProgramId" nillable="true" type="xs:int"/>
<xs:element minOccurs="0" maxOccurs="1" name="PLU" type="xs:string"/>
<xs:element minOccurs="1" maxOccurs="1" name="Quantity" type="xs:int"/>
</xs:sequence>
</xs:complexType>
编辑 2: 采纳 Leigh 的建议
以Psuedo-Code为模板,一步一个脚印
1) 创建需要传递的项目。
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
myItem 的 cfdump 揭示了以下方法:
根据文档,参数的顺序是PluSalesProgramId
,PLU
,Quantity
。
2) 将信息添加到项目中。
<cfset myItem.setPluSalesProgramId(JavaCast("int", "1"))>
<cfset myItem.setPLU(JavaCast("string", "123456"))>
<cfset myItem.setQuantity(JavaCast("int", "1"))>
跳过这一步。 *
3) 将项目添加到 CF 数组。
<cfset itemArray = newArray(1)>
<cfset arrayAppend(itemArray, myItem)>
itemArray
的转储如下:
到目前为止一切顺利。
4) 接下来,将对 myItem
的引用添加到 ArrayOfSmartOrderLineRequest
.
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<cfset orderItems.getSmartOrderLineRequest().add(myItem)>
5) 最后,orderItems
到myOrder
方法:
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
orderItems
)>
耶!成功了!我必须检查代码以确保一切都正确完成,但查看日志,看起来 SOAP 消息已正确发送,并且返回了 PLU not found 的预期错误。
Leigh,如果你把一个东西作为答案,我回到办公室后会接受它作为答案。
(评论摘要)
尽管名称为 ArrayOf,但我怀疑 ArrayOfSmartOrderLineRequest
class 更像是数组的包装器(或 java.util.List), similar to ArrayOfString。可以您 post a) class 的基本 shell(变量等)和 b) 如果可能,从 WSDL 定义该对象?
更新 1:
所以项目 class,即 SmartOrderLineRequest
,具有三 (3) 个主要值:PluSalesProgramId、PLU 和数量?你应该能够
- 创建一个常规 CF 数组并将
SmartOrderLineRequest
的实例附加到它
- 将 CF 数组传递到包装器 class 即
ArrayOfSmartOrderLineRequest
,替换 底层 List
- 最后,将包装器对象即 ArrayOfSmartOrderLineRequest(不是基础列表)传递到适当的方法中。
显然完全未经测试,但像这样:
<!--- UNTESTED PSUEDO-CODE.... --->
<!--- create one or more items .... --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.setPLU( JavaCast("string", "123456") )>
<cfset myItem.setPluSalesProgramId( JavaCast("int", 111) )>
<cfset myItem.setQuantity( JavaCast("int", 25) )>
<!--- append items to array --->
<cfset itemArray = []>
<cfset arrayAppend(itemArray, myItem)>
<!--- pass array into wrapper object --->
<cfset wrapper = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<!--- either using syntax 1 --->
<cfset wrapper.setSmartOrderLineRequest( itemArray )>
<!--- ... or possibly syntax 2 --->
<cfset wrapper.SmartOrderLineRequest = itemArray >
<!--- finally, pass wrapper object to appropriate method --->
<cfset orderObject = createObject("java", "com.USOrlando").myOrder(
....
, wrapper )>
更新二:
上面应该可以工作,但如果由于某种原因它不工作,..您也可以完全跳过 CF 数组并将单个 item(s) 添加到底层列出来。然后将包装器对象即 ArrayOfSmartOrderLineRequest 实例传递给所需的方法。
<!--- create one or more items .... --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.setPLU( JavaCast("string", "123456") )>
<cfset myItem.setPluSalesProgramId( JavaCast("int", 111) )>
<cfset myItem.setQuantity( JavaCast("int", 25) )>
<!--- append items directly to wrapper object --->
<cfset wrapper = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<cfset wrapper.getSmartOrderLineRequest().add( itemArray )>
....
<!--- finally, pass wrapper object to appropriate method --->
<cfset orderObject = createObject("java", "com.USOrlando").myOrder(
....
, wrapper )>
这是这个问题的延续:WCF and ColdFusion
因此,我设法使用 Metro 和导入 WSDL 获得了一个 JAR。我的主要 class 具有以下功能:getVersion()
和我的实现 myVersion()
、cancelOrder()
和 myCancel()
,最后是 placeOrder
和 myOrder()
.
对于前两种方法(getVersion
和 cancelOrder
),我能够传递正确的信息并从 Web 服务获得响应:
比如在myVersion
方法中调用webservice,输出版本号加上传入的字符串:
<cfset var.myVersion = createObject("java", "com.USOrlando").myVersion(
javaCast("string", "Batman")
)>
<!---Output is [version number] + "I'm Batman" --->
使用相同的模板,我还可以在 myOrder
方法中传递所有其他参数,除了类型为 org.tempuri.ArrayOfSmartOrderLineRequest
.
这是我不自信的地方,可能需要指导:
在浏览文档和生成的 classes 时,我会将文档中的内容放在块引号中以及我对它们的理解。
myOrder
应该获取通过 ColdFusion 传入的所有参数并将其放入 request
对象中。
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
JavaCast("org.tempuri.ArrayOfSmartOrderLineRequest", orderItems)
)>
最后一行 JavaCast("org.tempuri.ArrayOfSmartOrderLineRequest", orderItems)
是我的问题。我得到一个
JavaCast type org.tempuri.ArrayOfSmartOrderLineRequest must be one of the following types: byte, char, short, int, long, float, double, boolean, string, bigdecimal, their corresponding array representation (eg : int[]), or null.
错误,有道理。如果我将其设为 null
,则不会向 SoapMessage 传递任何内容。
我的问题是:如何传递最后一个参数?
orderItems
是一个 CF 变量,我相信它引用了一个 Java 对象。
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PluSalesProgramId = myItem.setPLU(1)>
<cfset myItem.PLU = myItem.setPLU("123456")>
<cfset myItem.Quantity = myItem.setPLU(1)>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
逆向计算,ArrayOfSmartOrderLineRequest.java
有一个方法 getSmartOrderLineRequest
。根据生成的 java 文件中的注释:
This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make to the returned list will be present inside the JAXB object. This is why there is not a
set
method for the smartOrderLineRequest property. It continues on to: For example, to add a new item, do as follows:getSmartOrderLineRequest().add(newItem);
我认为这意味着我必须创建一个 newItem
对象并将其传递给 getSmartOrderLineRequest
的 add
方法,对吗?因此,在构建 newItem
对象时,我创建了 myItem
变量,它具有三个属性:PLU
、PluSalesProgramId
和 Quantity
.
在我的脑海中,我正在CF中创建一个myItem
对象,它被保存在Java中,然后告诉Java方法getSmartOrderLineRequest
"Hey, ADD myItem
to your array."
如有任何帮助,我们将不胜感激。我觉得我快到了,但我不知道我应该朝哪个方向前进。
编辑 1: 对 Leigh 评论的回应。
当我单独传递对象时会发生什么,这不是一个愚蠢的问题。我重新创建了以下步骤,但出现了一个奇怪的错误:起初,我尝试了以下操作:
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PluSalesProgramId = myItem.PluSalesProgramId(JavaCast("int", "1"))>
<cfset myItem.PLU = myItem.setPLU(JavaCast("string", "123456"))>
<cfset myItem.Quantity = myItem.setPLU(JavaCast("int", "1"))>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
<!---Errors out on myItem.Quantity --->
我试过下面的代码,没有报错:
<!---Create Items --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.PLU = myItem.setPLU(JavaCast("string", "123456"))>
<!---Add Item --->
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest").getSmartOrderLineRequest().add(myItem)>
<!---Errors out on myItem.Quantity --->
我使用以下方式传递它:
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
orderItems
)>
<!---Returned Method Not Found error --->
下面是ArrayOfSmartOrderLineRequest.java的shell:
public class ArrayOfSmartOrderLineRequest {
@XmlElement(name = "SmartOrderLineRequest", nillable = true)
protected List<SmartOrderLineRequest> smartOrderLineRequest;
public List<SmartOrderLineRequest> getSmartOrderLineRequest() {
if (smartOrderLineRequest == null) {
smartOrderLineRequest = new ArrayList<SmartOrderLineRequest>();
}
return this.smartOrderLineRequest;
}
}
以下是 WSDL 中对象的定义:
<xs:complexType name="ArrayOfSmartOrderLineRequest">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="SmartOrderLineRequest" nillable="true" type="tns:SmartOrderLineRequest"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SmartOrderLineRequest">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="PluSalesProgramId" nillable="true" type="xs:int"/>
<xs:element minOccurs="0" maxOccurs="1" name="PLU" type="xs:string"/>
<xs:element minOccurs="1" maxOccurs="1" name="Quantity" type="xs:int"/>
</xs:sequence>
</xs:complexType>
编辑 2: 采纳 Leigh 的建议
以Psuedo-Code为模板,一步一个脚印
1) 创建需要传递的项目。
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
myItem 的 cfdump 揭示了以下方法:
根据文档,参数的顺序是PluSalesProgramId
,PLU
,Quantity
。
2) 将信息添加到项目中。
<cfset myItem.setPluSalesProgramId(JavaCast("int", "1"))>
<cfset myItem.setPLU(JavaCast("string", "123456"))>
<cfset myItem.setQuantity(JavaCast("int", "1"))>
跳过这一步。 *
3) 将项目添加到 CF 数组。
<cfset itemArray = newArray(1)>
<cfset arrayAppend(itemArray, myItem)>
itemArray
的转储如下:
到目前为止一切顺利。
4) 接下来,将对 myItem
的引用添加到 ArrayOfSmartOrderLineRequest
.
<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<cfset orderItems.getSmartOrderLineRequest().add(myItem)>
5) 最后,orderItems
到myOrder
方法:
<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
JavaCast("String", ExternalOrderId),
JavaCast("int", CustomerID),
.
.
.
JavaCast("String", Phone),
JavaCast("String", Email),
orderItems
)>
耶!成功了!我必须检查代码以确保一切都正确完成,但查看日志,看起来 SOAP 消息已正确发送,并且返回了 PLU not found 的预期错误。
Leigh,如果你把一个东西作为答案,我回到办公室后会接受它作为答案。
(评论摘要)
尽管名称为 ArrayOf,但我怀疑 ArrayOfSmartOrderLineRequest
class 更像是数组的包装器(或 java.util.List), similar to ArrayOfString。可以您 post a) class 的基本 shell(变量等)和 b) 如果可能,从 WSDL 定义该对象?
更新 1:
所以项目 class,即 SmartOrderLineRequest
,具有三 (3) 个主要值:PluSalesProgramId、PLU 和数量?你应该能够
- 创建一个常规 CF 数组并将
SmartOrderLineRequest
的实例附加到它 - 将 CF 数组传递到包装器 class 即
ArrayOfSmartOrderLineRequest
,替换 底层 List - 最后,将包装器对象即 ArrayOfSmartOrderLineRequest(不是基础列表)传递到适当的方法中。
显然完全未经测试,但像这样:
<!--- UNTESTED PSUEDO-CODE.... --->
<!--- create one or more items .... --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.setPLU( JavaCast("string", "123456") )>
<cfset myItem.setPluSalesProgramId( JavaCast("int", 111) )>
<cfset myItem.setQuantity( JavaCast("int", 25) )>
<!--- append items to array --->
<cfset itemArray = []>
<cfset arrayAppend(itemArray, myItem)>
<!--- pass array into wrapper object --->
<cfset wrapper = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<!--- either using syntax 1 --->
<cfset wrapper.setSmartOrderLineRequest( itemArray )>
<!--- ... or possibly syntax 2 --->
<cfset wrapper.SmartOrderLineRequest = itemArray >
<!--- finally, pass wrapper object to appropriate method --->
<cfset orderObject = createObject("java", "com.USOrlando").myOrder(
....
, wrapper )>
更新二:
上面应该可以工作,但如果由于某种原因它不工作,..您也可以完全跳过 CF 数组并将单个 item(s) 添加到底层列出来。然后将包装器对象即 ArrayOfSmartOrderLineRequest 实例传递给所需的方法。
<!--- create one or more items .... --->
<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
<cfset myItem.setPLU( JavaCast("string", "123456") )>
<cfset myItem.setPluSalesProgramId( JavaCast("int", 111) )>
<cfset myItem.setQuantity( JavaCast("int", 25) )>
<!--- append items directly to wrapper object --->
<cfset wrapper = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<cfset wrapper.getSmartOrderLineRequest().add( itemArray )>
....
<!--- finally, pass wrapper object to appropriate method --->
<cfset orderObject = createObject("java", "com.USOrlando").myOrder(
....
, wrapper )>