Mule 4:根据 Mule 4 中有效载荷的数据类型检查和应用条件的最安全方法是什么?

问题描述

场景: 我有一个有效载荷如下:

{
    "message": "Hello World!"
}

目标:需要检查“message”字段的数据类型并对其应用if else条件。

尝试了一些方法如下 类型 1:

payload.message is String

类型 2:

typeOf(payload.message) ~= "String"

类型 3:

(typeOf(payload.message) as String) == "String"

在这些中,根据负载的数据类型检查和应用 if else 条件的最可靠方法是什么?

注意: 类型 2 强制左侧值匹配并检查它是否等于右侧,所以我确定这不是一个好主意。请对 1 和 3 有任何想法吗?

解决方法

如果要检查元素类型,请使用第一种方法:someElement is SomeType。此表达式返回一个布尔值,指示该字段是否为所需类型。使用这种方法编写 if 语句比将 typeOf 函数的结果与字符串进行比较更简洁(尽管两者的工作方式相同)。请注意,如果元素为 null,则表达式的计算结果为 false。

您也可以选择第二个选项。当您使用 typeOf 函数时,它将返回一个表示元素类型的字符串。请注意,如果该字段为空,则 typeOf 将返回“Null”。如果要在输出中显示字段类型,可以使用 typeOf。例如:

%dw 2.0
output application/json
---
payload pluck ((value,key,index) -> 
    {
        fieldName: key,fiedValue: value,fieldType: typeOf(value)
    }
) 

使用您提供的输入负载,将导致:

[
    {
        "fieldName": "message","fiedValue": "Hello world!","fieldType": "String"
    }
]

关于“~=”运算符的一个注意事项:当您想与不确定其类型的元素进行比较时,通常会使用此运算符。 DataWeave 将尝试将它们强制转换为通用类型并进行实际比较。以下示例说明了这一点:

%dw 2.0
output application/json
---
{
    comparisonWithoutCoerce: (1 == "1"),comparisonWithCoerce: (1 ~= "1")
}

将返回:

{
    "comparisonWithoutCoerce": false,"comparisonWithtCoerce": true
}

最后,第三种方法可能会给出错误的答案:您将 payload.message 转换为字符串,然后检查结果是否为字符串。只有当 message 实际上是一个字符串时,这才会给你一个正确的答案。为了表明第三种方法不起作用,请检查以下情况:

输入有效载荷:

{
    "boolValue": true,"numValue": 12345,"strValue": "This is a test"
}

使用以下 DataWeave 表达式:

%dw 2.0
output application/json
---
payload pluck ((value,index) ->     {
        fieldName: key,fieldType: typeOf(value),fieldType2: typeOf(value as String)
    }
)

将导致:

[
  {
    "fieldName": "boolValue","fiedValue": true,"fieldType": "Boolean","fieldType2": "String"
  },{
    "fieldName": "numValue","fiedValue": 12345,"fieldType": "Number",{
    "fieldName": "strValue","fiedValue": "This is a test","fieldType": "String","fieldType2": "String"
  }
]

此外,如果某些字段是数组,则 Dataweave 表达式将失败,因为它无法将数组强制转换为字符串。

,

为简单起见,您可以只使用 typeOf(value) 并使用强制转换 (ie: String,Array,Number,Boolean,Object,Null,DateTime,...)

见:

示例:

typeOf(payload.message) ~= "String"