在ColdFusion中传递Java对象

这是这个问题的延续:
WCF and ColdFusion

所以我设法让JAR使用Metro并导入WSDL.我的主类有以下函数:getVersion()和我的实现myVersion(),cancelOrder()和myCancel(),最后是placeOrder和myOrder().

《在ColdFusion中传递Java对象》

我能够传递正确的信息并从webservices获得前2个方法的响应(getVersion和cancelOrder):

例如,在myVersion方法中,它调用webservice并输出版本号加上传递的字符串:

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

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

这是我不自信的地方,可能需要指导:

在浏览文档和生成的类时,我将把文档中的内容放在块引号中,以及我如何理解它们.

myOrder应该通过ColdFusion传递所有参数并将其放入请求对象中.

<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方法getSmartOrderLineRequest“嘿,将myItem添加到你的数组中”.

任何帮助将不胜感激.我觉得我几乎就在那里,但我不知道我应该向哪个方向前进.

编辑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显示以下方法:

《在ColdFusion中传递Java对象》

根据文档,参数的顺序是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的转储如下:《在ColdFusion中传递Java对象》

到现在为止还挺好.

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的预期错误.

Leigh,如果你把一些东西作为答案,当我回到办公室时,我会接受它作为答案.

最佳答案 (评论摘要)

尽管名称ArrayOf,我怀疑ArrayOfSmartOrderLineRequest类更像是一个数组(或java.util.List)的包装,类似ArrayOfString.您可以发布)该类别的基本的shell(变量,等等)和b)如果可能的话,从WSDL定义该对象?

更新1:

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

>创建一个常规CF数组并向其附加SmartOrderLineRequest实例
>将CF数组传递给包装类,即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 )>

更新2:

以上应该工作,但如果由于某种原因,它不..你也可以完全跳过CF阵列和个别项目(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 )>
点赞