“如何解决`删除SerializeJSON()的默认字母顺序`

Kig*_*dka 6 coldfusion cfml

我正在尝试将请求中的序列化数据添加到需要维护数据特定顺序的第三方API,但是SerializeJSON以字母顺序排列,这破坏了第三方API要求的格式。有人可以帮我弄清楚吗

输入:

<cfset data ={
                "Booking": {
                    "ActionCode":"DI",
                    "AgencyNumber":"23",
                    "Touroperator":"TVR",
                    "BookingNumber":"323",
                },
                "Payment": {
                    "__type":"paymenttype",
                    "PaymentProfile": {
                        "Value": 4,
                        "Manual": false
                    },
                    "PaymentType": 4,
                    "PaymentAction":2,
                    "Details": {
                        "IBAN": "DE02120300000000202051",
                        "BIC": "BYLADEM1001"
                    }
                },
                "Login":{
                    "UserCode": "usercode",
                    "Password": "password"
                }
            }>
Run Code Online (Sandbox Code Playgroud)

SerializeJSON()在我的数据上使用此方法时:

SerializeJSON(data)
Run Code Online (Sandbox Code Playgroud)

电流输出

"{"Booking":{"Touroperator":"TVR","ActionCode":"DI","BookingNumber":"323","AgencyNumber":"23"},"Login":{"UserCode":"usercode","Password":"password"},"Payment":{"PaymentProfile":{"Manual":false,"Value":4},"PaymentType":4,"PaymentAction":2,"__type":"paymenttype","Details":{"BIC":"BYLADEM1001","IBAN":"DE02120300000000202051"}}}"
Run Code Online (Sandbox Code Playgroud)

预期产量:

"{"Booking":{"ActionCode":"DI","AgencyNumber":"23","Touroperator":"TVR","BookingNumber":"323",},"Payment":{"__type":"paymenttype","PaymentProfile":{"Value":4,"Manual":false},"PaymentType":4,"PaymentAction":2,"Details":{"IBAN":"DE02120300000000202051","BIC":"BYLADEM1001"}},"Login":{"UserCode":"usercode","Password":"password"}}"
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 7

ColdFusion中的结构是无序的HashMap,因此根本没有任何顺序。您可以通过使用保持插入顺序structNew("Ordered")(ColdFusion 2016引入)。不幸的是,您不能再使用文字语法了,但是我想您还是在动态地生成数据。

<cfset data = structNew("Ordered")>

<cfset data["Booking"] = structNew("Ordered")>
<cfset data["Booking"]["ActionCode"] = "DI">
<cfset data["Booking"]["AgencyNumber"] = "TVR">
<cfset data["Booking"]["BookingNumber"] = "323">

<cfset data["Payment"] = structNew("Ordered")>
<cfset data["Payment"]["__type"] = "paymenttype">
<cfset data["Payment"]["PaymentProfile"] = structNew("Ordered")>
<cfset data["Payment"]["PaymentProfile"]["Value"] = 4>
<cfset data["Payment"]["PaymentProfile"]["Manual"] = false>

etc.
Run Code Online (Sandbox Code Playgroud)

如果您坚持使用较旧的ColdFusion版本,则必须使用Java的LinkedHashMap。

<cfset data = createObject("java", "java.util.LinkedHashMap")>

<cfset data["Booking"] = createObject("java", "java.util.LinkedHashMap")>
<cfset data["Booking"]["ActionCode"] = "DI">
<cfset data["Booking"]["AgencyNumber"] = "TVR">
<cfset data["Booking"]["BookingNumber"] = "323">

<cfset data["Payment"] = createObject("java", "java.util.LinkedHashMap")>
<cfset data["Payment"]["__type"] = "paymenttype">
<cfset data["Payment"]["PaymentProfile"] = createObject("java", "java.util.LinkedHashMap")>
<cfset data["Payment"]["PaymentProfile"]["Value"] = 4>
<cfset data["Payment"]["PaymentProfile"]["Manual"] = false>

etc.
Run Code Online (Sandbox Code Playgroud)

但是请注意:LinkedHashMap区分大小写(并且区分大小写:如果您的键是数字,那确实很重要!)。

<cfset data = createObject("java", "java.util.LinkedHashMap")>

<cfset data["Test"] = "">
<!---
    accessing data["Test"] = works
    accessing data["test"] = doesn't work
    accessing data.Test    = doesn't work
--->
Run Code Online (Sandbox Code Playgroud)

您可能会遇到的另一个问题:由于ColdFusion的内部类型转换,serializeJSON()可能会以意想不到的方式对数字和布尔值进行字符串化处理。就像是:

<cfset data = structNew("Ordered")>
<cfset data["myBoolean"] = true>
<cfset data["myInteger"] = 123>
Run Code Online (Sandbox Code Playgroud)

可能很容易像这样结束:

{
    "myBoolean": "YES",
    "myInteger": 123.0
}
Run Code Online (Sandbox Code Playgroud)

(注意:上面的文字语法完全可以正常工作,但是如果将值作为变量/参数传递,则最终会进行强制转换。)

最简单的解决方法是在序列化之前显式转换值:

<cfset data = structNew("Ordered")>
<cfset data["myBoolean"] = javaCast("boolean", true)>
<cfset data["myInteger"] = javaCast("int", 123)>
Run Code Online (Sandbox Code Playgroud)