You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSO2微集成器中VFS传输写入TXT文件无响应问题

问题:WSO2 Micro Integrator中API响应写入TXT文件无返回的排查解决

我在WSO2 Micro Integrator中开发了如下API配置,需要将API响应写入TXT文件,尝试用VFS传输配置实现,但未收到返回响应,求排查解决。

原API配置

<?xml version="1.0" encoding="UTF-8"?>
<api context="/example2" name="Example2" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST GET">
        <inSequence>
            <clone>
                <target>
                    <sequence>
                        <property description="requestObject" expression="json-eval($)" name="requestObject" scope="default" type="STRING"/>
                        <log description="logRequest" level="custom" separator=",">
                            <property expression="json-eval($)" name="logRequestObject"/>
                        </log>
                        <propertyGroup description="splitRequest">
                            <property expression="json-eval($.client)" name="JSON_CLIENT" scope="default" type="INTEGER"/>
                            <property expression="json-eval($.user)" name="JSON_USER" scope="default" type="STRING"/>
                            <property expression="json-eval($.pass)" name="JSON_PASS" scope="default" type="STRING"/>
                        </propertyGroup>
                        <log description="logRequest" level="custom" separator=",">
                            <property expression="json-eval($.client)" name="LOG_CLIENT"/>
                            <property expression="json-eval($.user)" name="LOG_USER"/>
                            <property expression="json-eval($.pass)" name="LOG_PASS"/>
                        </log>
                        <payloadFactory media-type="json">
                            <format>{&#xd;
                                "clientId":$1,&#xd;
                                "userName":"$2",&#xd;
                                "password":"$3"&#xd;
                            }</format>
                            <args>
                                <arg evaluator="xml" expression="get-property('JSON_CLIENT')"/>
                                <arg evaluator="xml" expression="get-property('JSON_USER')"/>
                                <arg evaluator="xml" expression="get-property('JSON_PASS')"/>
                            </args>
                        </payloadFactory>
                        <call>
                            <endpoint key="ex2_org60"/>
                        </call>
                        <property description="responseObject" expression="json-eval($)" name="responseObject" scope="default" type="STRING"/>
                        <log description="logResponseReturn" level="custom" separator=",">
                            <property expression="json-eval($)" name="logResponse"/>
                        </log>
                        <dbreport>
                            <connection>
                                <pool>
                                    <driver>org.postgresql.Driver</driver>
                                    <url>jdbc:postgresql://localhost:5432/idempiere</url>
                                    <user>postgres</user>
                                    <password>viethoan2k1</password>
                                </pool>
                            </connection>
                            <statement>
                                <sql><![CDATA[
                                      INSERT INTO "adempiere"."sts_log_api" ("ad_client_id", "ad_org_id", "createdby", "updatedby", "request", "response", "date")
                                      VALUES (1001, 2001, 5001, 5001, ?, ?, '2023-08-17 12:00:00.000000');
                                  ]]></sql>
                                <parameter expression="get-property('requestObject')" type="VARCHAR"/>
                                <parameter expression="get-property('responseObject')" type="VARCHAR"/>
                            </statement>
                        </dbreport>
                        <propertyGroup>
                            <property expression="json-eval($.success)" name="success" scope="default" type="BOOLEAN"/>
                            <property expression="json-eval($.error.message)" name="error" scope="default" type="STRING"/>
                        </propertyGroup>
                        <payloadFactory media-type="json">
                              <format>{&#xd;
                                  "source":"may60",&#xd;
                                "success":$1,&#xd;
                                  "error":"$2"&#xd;
                              }</format>
                            <args>
                                <arg evaluator="xml" expression="get-property('success')"/>
                                <arg evaluator="xml" expression="get-property('error')"/>
                            </args>
                        </payloadFactory>
                    </sequence>
                </target>
            </clone>
            <respond/>
            
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>

尝试的VFS传输配置

<log level="full"/>
<send>
    <endpoint>
        <address uri="vfs:file:///D:/log1.txt">
            <suspendOnFailure>
                <initialDuration>-1</initialDuration>
                <progressionFactor>1</progressionFactor>
            </suspendOnFailure>
            <markForSuspension>
                <retriesBeforeSuspension>0</retriesBeforeSuspension>
            </markForSuspension>
        </address>
    </endpoint>
</send>

排查与修复方案

核心问题分析

  1. 异步分支导致提前响应:原API用<clone>创建异步分支,但主流程直接执行<respond>,此时分支还未完成响应处理,客户端会收到空响应。
  2. VFS配置位置错误:VFS的send未嵌入到正确的处理流程中,无法捕获最终响应内容。
  3. VFS参数缺失:未配置文件写入模式(如追加),可能导致文件写入异常。

修改后的完整API配置

<?xml version="1.0" encoding="UTF-8"?>
<api context="/example2" name="Example2" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST GET">
        <inSequence>
            <property description="requestObject" expression="json-eval($)" name="requestObject" scope="default" type="STRING"/>
            <log description="logRequest" level="custom" separator=",">
                <property expression="json-eval($)" name="logRequestObject"/>
            </log>
            <propertyGroup description="splitRequest">
                <property expression="json-eval($.client)" name="JSON_CLIENT" scope="default" type="INTEGER"/>
                <property expression="json-eval($.user)" name="JSON_USER" scope="default" type="STRING"/>
                <property expression="json-eval($.pass)" name="JSON_PASS" scope="default" type="STRING"/>
            </propertyGroup>
            <log description="logRequest" level="custom" separator=",">
                <property expression="json-eval($.client)" name="LOG_CLIENT"/>
                <property expression="json-eval($.user)" name="LOG_USER"/>
                <property expression="json-eval($.pass)" name="LOG_PASS"/>
            </log>
            <payloadFactory media-type="json">
                <format>{&#xd;
                    "clientId":$1,&#xd;
                    "userName":"$2",&#xd;
                    "password":"$3"&#xd;
                }</format>
                <args>
                    <arg evaluator="xml" expression="get-property('JSON_CLIENT')"/>
                    <arg evaluator="xml" expression="get-property('JSON_USER')"/>
                    <arg evaluator="xml" expression="get-property('JSON_PASS')"/>
                </args>
            </payloadFactory>
            <call>
                <endpoint key="ex2_org60"/>
            </call>
            <property description="responseObject" expression="json-eval($)" name="responseObject" scope="default" type="STRING"/>
            <log description="logResponseReturn" level="custom" separator=",">
                <property expression="json-eval($)" name="logResponse"/>
            </log>
            <dbreport>
                <connection>
                    <pool>
                        <driver>org.postgresql.Driver</driver>
                        <url>jdbc:postgresql://localhost:5432/idempiere</url>
                        <user>postgres</user>
                        <password>viethoan2k1</password>
                    </pool>
                </connection>
                <statement>
                    <sql><![CDATA[
                          INSERT INTO "adempiere"."sts_log_api" ("ad_client_id", "ad_org_id", "createdby", "updatedby", "request", "response", "date")
                          VALUES (1001, 2001, 5001, 5001, ?, ?, '2023-08-17 12:00:00.000000');
                      ]]></sql>
                    <parameter expression="get-property('requestObject')" type="VARCHAR"/>
                    <parameter expression="get-property('responseObject')" type="VARCHAR"/>
                </statement>
            </dbreport>
            <propertyGroup>
                <property expression="json-eval($.success)" name="success" scope="default" type="BOOLEAN"/>
                <property expression="json-eval($.error.message)" name="error" scope="default" type="STRING"/>
            </propertyGroup>
            <payloadFactory media-type="json">
                  <format>{&#xd;
                      "source":"may60",&#xd;
                    "success":$1,&#xd;
                      "error":"$2"&#xd;
                  }</format>
                <args>
                    <arg evaluator="xml" expression="get-property('success')"/>
                    <arg evaluator="xml" expression="get-property('error')"/>
                </args>
            </payloadFactory>
            <!-- 配置VFS写入参数,追加模式写入文件 -->
            <property name="vfs.append" value="true" scope="transport"/>
            <send>
                <endpoint>
                    <address uri="vfs:file:///D:/log1.txt">
                        <suspendOnFailure>
                            <initialDuration>-1</initialDuration>
                            <progressionFactor>1</progressionFactor>
                        </suspendOnFailure>
                        <markForSuspension>
                            <retriesBeforeSuspension>0</retriesBeforeSuspension>
                        </markForSuspension>
                    </address>
                </endpoint>
            </send>
            <!-- 返回最终响应给客户端 -->
            <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>

关键修改点说明

  1. 移除<clone>:原场景无需异步分支,移除后保证流程同步执行,所有处理完成后再返回响应。
  2. 添加VFS追加属性:vfs.append=true确保每次写入内容追加到文件末尾,避免覆盖原有内容。
  3. 调整VFS位置:将VFS的send放到最终payloadFactory之后,确保写入的是最终要返回给客户端的响应内容。
  4. 权限检查:确保WSO2 MI的运行用户拥有D盘的写入权限,可通过查看repository/logs/wso2carbon.log排查权限异常。

内容的提问来源于stack exchange,提问作者hoannv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 06:18:09