mule 4.4 community edition - 解析文件作为流读取

mule 4.4 community edition - parsing file read as stream

这个问题是我之前的问题 [此处][1] 的后续问题 感谢@aled 我正在使用 'set-payload' with expression.

正在读取文件并尝试解析并验证每一行。 Edit2:在下面添加了文件详细信息:(我需要验证文件的每一行都有一个价格值,在下面的示例中,订单项 'Butter' 没有价格,因此应该将其标记为错误,而其他行是好的并且它们应该作为 POST 请求发送给第三方 api

d1|Milk|3.9|
d2|Butter||
g1|Bread|1.6|
g2|Biscuits|3.4|
d3|Yogurt|5.5|
d4|Flavored Yogurt|5.5|
m1|Toothbrush|12|

文件读取是可重复的内存流
读取文件后,我正在使用 'set-payload' 设置负载。 这是此流程的完整代码:

<flow name="get:shoppingProducts" >
    <logger level="INFO" doc:name="Logger" message="get list of products request received "/>
    <file:read doc:name="Read file"  config-ref="File_Config" path="/product_master/test.unl" outputMimeType='application/csv; header=false; separator=|' outputEncoding="utf-8">
        <repeatable-in-memory-stream />
    </file:read>
    <choice doc:name="is the file empty ?" >
        <when expression="sizeOf(payload) == 0">
            <logger level="ERROR" doc:name="Payload is empty " message="Empty payload from File read !"/>
            <raise-error doc:name="Raise error on empty file " type="XYZ:EMPTY" description="Empty file"/>
        </when>
        <otherwise >
            <logger level="INFO" doc:name="Payload not empty"  message="All good"/>
        </otherwise>
    </choice>

    <set-payload value="#[output application/json

    ---

    payload map (value,index)->
    {
      id:value.column_0,
      description:value.column_1,
      price:value.column_2

     }]" doc:name="Set Payload" mimeType="application/json" encoding="UTF-8"  />

    <foreach doc:name="For Each file record" collection="#[payload]">
        <logger level="DEBUG" doc:name="Log record" message="#[payload.description]"/>
        <scripting:execute doc:name="Validate data" engine="Groovy">
            <scripting:code ><![CDATA[println("hello world 001");
            println(payload);
            println("hello world 002");
            println(message.getPayload());
            println("hello world 003");
            println(payload.description);]]></scripting:code>
        </scripting:execute>
    </foreach>
    <logger level="INFO" doc:name="Logger"  message="after reading products file  "/>

这似乎工作正常,我可以看到如下所示的有效载荷(在调用 set-payload 之后):

[
  {
    "id": "d1",
    "description": "Milk",
    "price": 3.9
  },
  {
    "id": "d2",
    "description": "Butter",
    "price": 4.5
  },
  ...
]

现在我尝试在 for 循环中迭代数据 for 循环中的第一个组件是 'Logger',它正在记录有效载荷描述:

<logger level="DEBUG" doc:name="Log record" message="hello we are here #[payload.description]"/>

这在日志中显示正常:

hello we are here "Milk"

(我是 运行 处于调试模式的代码),现在分钟控制到达我的 groovy 循环内的脚本,事情出错了...... 在调试中,有效载荷仍然正确显示为:

{
  "id": "d1",
  "description": "Milk",
  "price": "3.9"
}

然而,当我尝试在 groovy 脚本中访问其属性之一时,出现此错误:

"groovy.lang.MissingPropertyException: No such property: description for class: org.mule.runtime.core.internal.streaming.bytes.ManagedCursorStreamDecorator"

这是否会发生,因为我正在使用 'repeatable-in-memory-stream' 导致循环再次获取流而不是 json 有效负载?

我还尝试将文件读取更改为:不可重复流,但在这种情况下,我的设置有效负载脚本无法处理:

org.mule.runtime.module.extension.internal.runtime.result.AbstractReturnDelegate$ConnectedInputStreamWrapper@70ee7444

我做错了什么,请问如何改正?

问题出在您的 groovy 脚本上。您假设对象是特定的 Java class 并尝试直接访问它。在某些情况下,它可能是正确的,但您不能做出假设。它也完全不需要,因为 Mule 4 和 DataWeave 提供了一个直接替代你正在尝试做的事情(ir 一个记录器组件)。 Mule 4 是为用户设计的,以避免必须使用 Java 或 Groovy 来完成正常任务。

在您更新的评论和问题中,您明确表示需要验证价格字段是否为空。这是一个非常基本的验证,绝对没有必要为此走 Groovy/Java 路线。您可以在带有条件 isEmpty(payload.price) 的 foreach 循环内添加一个选择路由器,以验证价格是否为 null、空或空格(因为它是一个字符串,空格是有效检查)。 Mule built-in 组件知道如何透明地处理包含在流中的有效负载,您甚至不需要为处理流而烦恼。