m子4.4社区版 - 解析文件读为流

发布于 2025-01-19 05:29:00 字数 3477 浏览 3 评论 0原文

这个问题是我先前问题的后续[此处] [1] 多亏了@aled,我将“ set-payload”与表达式使用。

我正在读取文件并试图解析然后验证每一行。 EDIT2:下面添加的文件详细信息:(我需要验证文件的每一行都有一个价格值,在下面的示例订单项“黄油”中没有价格,因此应标记为错误,而其他行则良好,他们应该应该作为邮政请求发送到第三方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|

文件读数是一种可重复的记忆 - 流程
现在阅读文件后,使用“设定付费负载”设置有效载荷。 这是此流的完整代码:

<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  "/>

这似乎可以正常工作,我可以看到如下(调用设定付费后)的有效载荷:

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

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

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

这在日志中呈罚款:

你好,我们在这里“牛奶”

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

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

但是,当我尝试访问Groovy脚本中的其中一个属性时,请收到此错误:

“ groovy.lang.missingpropertyexception:否这样的属性:class:org.mule.runtime.core.core.internal.streaming.bytes.managedCursorStreamDecorator”

这可能会发生这种情况 ”导致循环再次获得流而不是JSON有效载荷?

我还尝试将文件更改为:不可重复的流,但是在这种情况下,我的设定付费脚本无法处理:

org.mule.runtime.module.extension.internal.runtime.runtime.runtime.abstractreterturndelegatequnnectionnectedInputStreamWrapper@70EE74444

$ connectedInputStreamWrapper@704444我在做什么错以及如何纠正此问题?

This question is a follow up to my earlier question [here][1]
Thanks to @aled I am using 'set-payload' with expression.

Am reading a file and trying to parse and then validate each row.
Edit2 : added File details below : ( I need to validate that each row of the file has a price value , in below example line item 'Butter' has no price so should be flagged as an error while the other rows are good and they should be sent as a POST request to a third party 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|

File reading is a repeatable-in-memory-stream
Now after reading the file , am setting the payload using 'set-payload'.
Here is the complete code of this flow :

<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  "/>

This seems to work fine and I can see payload like below ( after calling set-payload ) :

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

Now I am trying to iterate over the data in a for loop
First component in the for loop is a 'Logger' which is logging the payloads description:

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

This is showing up fine in logs:

hello we are here "Milk"

( I am running code in debug mode ) and now the minute control reaches my groovy script inside the for loop , things go wrong ...
In debug the payload still shows up correctly as :

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

However when I try and access one of its attributes in groovy script am getting this error:

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

Could this be happening because I am using 'repeatable-in-memory-stream' which is causing for loop to again get the stream rather than json payload ?

I also tried changing file read to : non-repeatable-stream but in this case my set-payload script is not able to handle :

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

What am I doing wrong and how to correct this please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最后的乘客 2025-01-26 05:29:00

问题是你的常规脚本。您假设这些对象是特定的 Java 类并尝试直接访问它。在某些情况下,这可能是正确的,但你不能做出假设。自 Mule 4 和 Mule 以来,它也完全不需要了。 DataWeave 为您尝试执行的操作(通过记录器组件)提供了直接替代方案。 Mule 4 的设计目的是让用户避免在正常任务中不得不求助于 Java 或 Groovy。

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

The problem is your groovy script. You are assuming the objects are a specific Java class and trying to access it directly. In some cases it may be true but you can not make assumptions. It also completely unneeded since Mule 4 & DataWeave provide a direct alternative to what you are trying to do (ir a logger component). Mule 4 is designed for users to avoid having to resort to Java or Groovy for normal tasks.

In your updated comments and question you made it clear that you need to validate that the price field is not null. That is a very basic validation and there is absolutely no need to go the Groovy/Java route for that. You can add a choice router inside the foreach loop with condition isEmpty(payload.price) to validate if the price is null, empty or spaces (since it is a string spaces is a valid check). Mule built-in components know to handle payloads that are contained in a stream transparently you don't even need to bother about handling streams.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文