ColdFusion不会保留将元素分配给结构的顺序。
在我的特定情况下,当我需要从该结构创建SOAP信封并且接收者需要以特定顺序在信封中进行数据处理时,这会带来问题。
从ColdFusion 2016及更高版本开始,StructNew()方法中提供了一个“类型”选项,您可以在其中指定“订购”。不幸的是,我仍然使用CF9.02 ...例如(在CF9中):
<cfscript>
myStruct=StructNew();
myStruct.one=StructNew();
myStruct.one.item1="Old Trafford";
myStruct.one.item2="Anfield";
myStruct.two=StructNew();
myStruct.two.item3="Stamford Bridge";
myStruct.two.item4="Villa Park";
myStruct.three=StructNew();
myStruct.three.item5="St James Park";
myStruct.three.item6="Emirates Stadium";
WriteDump(myStruct);
</cfscript>
输出:
{"ONE":{"ITEM2":"Anfield","ITEM1":"Old Trafford"},"THREE":{"ITEM6":"Emirates Stadium","ITEM5":"St James Park"},"TWO":{"ITEM4":"Villa Park","ITEM3":"Stamford Bridge"}}
如您所见,订单被打乱了。
第二个问题是大写。所有项目都转换为大写...
这是SOAP信封的问题,因为它区分大小写。
订购。
解决方案是使用Java LinkedHashMap,它可以像ColdFusion中的结构一样使用。
因此,我只需要替换
StructNew();
为:createObject("java", "java.util.LinkedHashMap").init();
大写:
通过字符串名称分配/寻址它们。这将保留情况。
因此,示例变为:
<cfscript>
myStruct=createObject("java", "java.util.LinkedHashMap").init();
myStruct['one']=createObject("java", "java.util.LinkedHashMap").init();
myStruct['one']['item1']="Old Trafford";
myStruct['one']['item2']="Anfield";
myStruct['two']=createObject("java", "java.util.LinkedHashMap").init();
myStruct['two']['item3']="Stamford Bridge";
myStruct['two']['item4']="Villa Park";
myStruct['three']=createObject("java", "java.util.LinkedHashMap").init();
myStruct['three']['item5']="St James Park";
myStruct['three']['item6']="Emirates Stadium";
WriteDump(SerializeJSON(myStruct));
</cfscript>
输出:
{"one":{"item1":"Old Trafford","item2":"Anfield"},"two":{"item3":"Stamford Bridge","item4":"Villa Park"},"three":{"item5":"St James Park","item6":"Emirates Stadium"}}
很好的秩序和案例保存!
这正是我们使用ColdFusion 8保留键顺序的方式。请注意,如果使用JSON或WDDX序列化数据,它将保留顺序,但是反序列化将忽略它。(如果反序列化时键顺序很重要,请考虑在序列化之前添加一个包含键特定顺序的数组。)
感谢有关反序列化的注意事项!这只是这里的示例所使用的,我在我的应用程序中将结构转换为XML(类似SOAP信封)。