在ColdFusion中传递Java对象

Che*_*ter 5 java coldfusion jar coldfusion-11

这是该问题的延续:WCF和ColdFusion

因此,我设法使用Metro并导入WSDL来使JAR正常工作。我的主类具有以下功能:getVersion()和实现myVersion()cancelOrder()以及myCancel()和,最后placeOrder还有和myOrder()

各种方法

对于前两种方法(getVersioncancelOrder),我能够传递正确的信息并从Web服务获得响应:

例如,在myVersion方法中,它调用Web服务并输出版本号和传递的字符串:

<cfset var.myVersion = createObject("java", "com.USOrlando").myVersion(
    javaCast("string", "Batman")
)>
<!---Output is [version number] + "I'm Batman" --->
Run Code Online (Sandbox Code Playgroud)

使用相同的模板,我还可以传递myOrder方法中除type的最后一个参数以外的所有其他参数org.tempuri.ArrayOfSmartOrderLineRequest

这是我不确定的地方,可能需要指导:

在阅读文档和生成的类时,我将在文档中用引号引起来,以及如何理解它们。

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)
)>
Run Code Online (Sandbox Code Playgroud)

最后一行JavaCast("org.tempuri.ArrayOfSmartOrderLineRequest", orderItems)是我的问题。我得到一个

JavaCast类型org.tempuri.ArrayOfSmartOrderLineRequest必须是以下类型之一:字节,字符,短型,整数,长型,浮点型,双精度型,布尔型,字符串,大十进制,其对应的数组表示形式(例如:int [])或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)>
Run Code Online (Sandbox Code Playgroud)

向后工作,ArrayOfSmartOrderLineRequest.java只有一个方法getSmartOrderLineRequest。根据生成的java文件中的注释:

此访问器方法返回对活动列表的引用,而不是快照。因此,您对返回列表所做的任何修改都将出现在JAXB对象中。这就是为什么没有set用于smartOrderLineRequest属性的 方法的原因。继续进行以下操作: 例如,要添加新项目,请执行以下操作: getSmartOrderLineRequest().add(newItem);

我的意思是我必须创建一个newItem对象并将其传递给add方法,对getSmartOrderLineRequest吗?因此,在建设newItem对象,我创建的myItem变量,它有三个属性:PLUPluSalesProgramIdQuantity

在我的脑海中,我正在myItemCF中创建一个对象,该对象保存在Java中,然后告诉Java方法getSmartOrderLineRequest“嘿,添加 myItem到数组中”。

任何帮助将不胜感激。我觉得自己快到了,但是我不知道应该朝哪个方向前进。

编辑1:回应李的评论。

当我仅通过对象本身时,会发生什么并不是一个愚蠢的问题。我重新创建了以下步骤,但出现一个奇怪的错误:首先,我尝试了以下操作:

<!---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 --->
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下代码,但没有错误:

<!---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 --->
Run Code Online (Sandbox Code Playgroud)

我通过使用它:

<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 --->
Run Code Online (Sandbox Code Playgroud)

以下是ArrayOfSmartOrderLineRequest.java的外壳:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是来自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>
Run Code Online (Sandbox Code Playgroud)

编辑2:听李的建议

使用伪代码作为模板,我一次迈出了一步。

1)创建需要传递的项目。

<cfset myItem = createObject("java", "org.tempuri.SmartOrderLineRequest")>
Run Code Online (Sandbox Code Playgroud)

myItem的cfdump显示以下方法:

cfdump myItem

根据该文件,该参数的顺序是PluSalesProgramIdPLUQuantity

2)将信息添加到项目中。

<cfset myItem.setPluSalesProgramId(JavaCast("int", "1"))>
<cfset myItem.setPLU(JavaCast("string", "123456"))>
<cfset myItem.setQuantity(JavaCast("int", "1"))>
Run Code Online (Sandbox Code Playgroud)

跳过这一步。* 3)将项目添加到CF阵列。

<cfset itemArray = newArray(1)>
<cfset arrayAppend(itemArray, myItem)>
Run Code Online (Sandbox Code Playgroud)

的转储itemArray如下:itemArray转储

到目前为止,一切都很好。

4)接着,添加参考myItemArrayOfSmartOrderLineRequest

<cfset orderItems = createObject("java", "org.tempuri.ArrayOfSmartOrderLineRequest")>
<cfset orderItems.getSmartOrderLineRequest().add(myItem)>
Run Code Online (Sandbox Code Playgroud)

5)最后,orderItemsmyOrder方法:

<cfset var.01_00_myOrder = createObject("java", "com.USOrlando").myOrder(
    JavaCast("String", ExternalOrderId),
    JavaCast("int", CustomerID),
    .
    .
    .
    JavaCast("String", Phone),
    JavaCast("String", Email),
    orderItems
)>
Run Code Online (Sandbox Code Playgroud)

好极了!可行!我将必须检查一下代码以确保一切都正确完成,但是通过日志查看,看起来SOAP消息已正确发送,并且未找到预期的PLU错误。

好吧,如果您把东西作为答案,当我回到办公室时,我会接受它作为答案。

Lei*_*igh 2

(评论总结)

尽管名称为ArrayOf,但我怀疑该类ArrayOfSmartOrderLineRequest更像是数组(或java.util.List)的包装器,类似于ArrayOfString。您能否发布 a) 该类的基本外壳(变量等)和 b) 如果可能的话,来自 WSDL 的该对象的定义?

更新1:

因此,项目类(即 )SmartOrderLineRequest具有三 (3) 个主要值:PluSalesProgramId、PLU 和 Quantity?你应该能够

  1. 创建一个常规 CF 数组并将其实例附加SmartOrderLineRequest到其中
  2. 将 CF 数组传递到包装类 ie 中ArrayOfSmartOrderLineRequest替换底层List
  3. 最后,将包装器对象,即 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 )>
Run Code Online (Sandbox Code Playgroud)

更新2:

上面的方法应该可以工作,但如果由于某种原因不能,..您也可以完全跳过 CF 数组,并将单个项目添加到基础列表中。然后将包装对象(即 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 )>
Run Code Online (Sandbox Code Playgroud)