WSO2 ESB - 在有效负载的标记内使用XML数据调用Webservices

时间:2015-08-19 07:53:50

标签: wso2 cdata

我需要通过中间件调用外部Web服务,其中我的有效负载中的一个标签包含嵌入式XML。下面的示例有效负载和序列片段。我遇到了以下问题。

场景1 :(第24行)表达式=" get-property(' PayloadXML')" - 发出send命令后,无法识别Web服务方法。

场景2 :(第24行)表达式=" get-property(' lPayload')" - 发出send命令后,将成功调用webservice方法。但是,要使目标系统成功处理消息,它需要处理CDATA元素(包装)。

尝试通过soapUI调用方案2时,该过程成功。根据我所研究的内容(Passing CDATA in WSO2),soapUI似乎在转发消息之前在内部处理CDATA元素。

现在,我理解我设置方案2的方式并不理想(更多的是黑客攻击),但我并不知道有任何其他方法可以实现这一点。我已经阅读了很多博客/帖子,并尝试通过XSLT调解器转换(开发)Payload而没有运气。我还发现了以下帖子http://www.yenlo.com/en/how-to-preserve-a-cdata-in-xml-that-is-circulating-in-a-wso2-enterprise-service-bus/,但我似乎无法找到正在引用的补丁。

所以我的问题如下: 1.我有没有其他方法/机制来达到我的要求? 2. WSO2 ESB 4.9.0版本是否会解决上述问题?

示例有效负载:

<sample><test>MyData</test></sample>

序列片段:

     <property xmlns:ns1="http://ws.wso2.org/dataservice"
               xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
               name="PayloadXML"
               expression="$body/data-services-event/content/ns1:return/ns1:return/ns1:PayLoadXML"/>
     <property xmlns:ns="http://org.apache.synapse/xsd"
               name="lPayload"
               expression="fn:concat(fn:concat('&lt;![CDATA[',get-property('PayloadXML')), ']]&gt;')"/>
     <payloadFactory media-type="xml">
        <format>
           <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                             xmlns:log="http://mynamespace">
              <soapenv:Header/>
              <soapenv:Body>
                 <log:publishMessage>
                    <Payload xmlns="">$1</Payload>
                 </log:publishMessage>
              </soapenv:Body>
           </soapenv:Envelope>
        </format>
        <args>
           <arg xmlns:ns2="http://org.apache.synapse/xsd"
                xmlns:ns="http://org.apache.synapse/xsd"
                evaluator="xml"
                expression="get-property('lPayload')"/>
        </args>
     </payloadFactory>

2 个答案:

答案 0 :(得分:2)

这是一个示例代理服务,它接收XML数据并在CDATA部分中发回带有输入内容子部分的新XML消息。

发送:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <PayloadXML>
            <sample><test>MyData</test></sample>
        </PayloadXML>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

您收到:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header/>
    <soapenv:Body>
        <log:publishMessage xmlns:log="http://mynamespace">
            <Payload><![CDATA[<sample><test>MyData</test></sample>]]></Payload>
        </log:publishMessage>
    </soapenv:Body>
</soapenv:Envelope>

代理def:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" statistics="disable" trace="disable" startOnLoad="true">
    <target>
        <inSequence>
            <!-- extract xml content from the input message -->
            <property name="xmlContent" expression="$body/PayloadXML/*[1]" type="OM"/>
            <!-- compose a new message -->
            <enrich>
                <source type="inline" clone="true">
                    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                        <soapenv:Header/>
                        <soapenv:Body>
                            <log:publishMessage xmlns:log="http://mynamespace">
                                <Payload xmlns=""/>
                            </log:publishMessage>
                        </soapenv:Body>
                    </soapenv:Envelope>
                </source>
                <target type="envelope"/>
            </enrich>
            <!-- create a CDATA section for 'Payload' node -->
            <script language="js">
                importPackage(Packages.org.apache.axiom.om);
                var payloadElmt = mc.getEnvelope().getBody().getFirstElement().getFirstElement();
                var omText = payloadElmt.getOMFactory().createOMText(payloadElmt, mc.getProperty("xmlContent"), OMNode.CDATA_SECTION_NODE);
                payloadElmt.addChild(omText)                    
            </script>
            <!-- send back this new message as a response for the caller -->
            <header name="To" action="remove"/>
            <property name="RESPONSE" value="true"/>
            <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
            <send/>
        </inSequence>
    </target>
    <description/>
</proxy>

答案 1 :(得分:1)

如果您的基本要求是在标记内传递xml数据,以下是一个示例。

这里我使用的是wso2 ESB 4.9.0。基本的是,您需要将有效负载工厂格式存储在注册表中,并在有效负载工厂配置中使用它。如下所示。

<proxy xmlns="http://ws.apache.org/ns/synapse"
   name="foo"
   transports="https,http"
   statistics="disable"
   trace="disable"
   startOnLoad="true">
<target>
    <inSequence>
        <property xmlns:ns="http://org.apache.synapse/xsd"
                  name="Request"
                  expression="$body/child::*[fn:position()=1]"
                  scope="default"
                  type="STRING"/>
        <payloadFactory media-type="xml">
            <format key="conf:/repository/esb/myPF"/>
            <args>
                <arg evaluator="xml" expression="$ctx:Request"/>
                <arg value="1"/>
            </args>
        </payloadFactory>

        <send>
            <endpoint>
                <address uri="http://127.0.0.1:9763/services/Hello"/>
            </endpoint>
        </send>
    </inSequence>
    <outSequence>
        <send/>
    </outSequence>
</target>
<description/>

以上是我的代理服务。我从请求ESB从客户端获取第一个子节点并将其用作有效负载工厂中介的输入。

注册表资源的内容如下所示。

<ns:testMethod xmlns:ns="http://example.com">
                            <xs:xmlBody xmlns:xs="http://example.com"><![CDATA[$1]]></xs:xmlBody>
                            <xs:sessionId xmlns:xs="http://example.com">$2</xs:sessionId>
                        </ns:testMethod>

您可以通过为ESB [2]启用wirelog来测试方案。

这里我在WSO2 AS中托管了一个简单的axis2服务进行测试。这是wirelog输出。

   [2016-02-24 19:02:24,696] DEBUG - wire << "POST /services/Hello HTTP/1.1[\r][\n]"
 [2016-02-24 19:02:24,696] DEBUG - wire << "Content-Type: application/soap+xml; charset=UTF-8; action="urn:mediate"[\r][\n]"
 [2016-02-24 19:02:24,696] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"
 [2016-02-24 19:02:24,696] DEBUG - wire << "Host: 127.0.0.1:9763[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "180[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns:testMethod xmlns:ns="http://example.com"><xs:xmlBody xmlns:xs="http://example.com"><![CDATA[<sample><test>MyData</test></sample>]]></xs:xmlBody><xs:sessionId xmlns:xs="http://example.com">1</xs:sessionId></ns:testMethod></soapenv:Body></soapenv:Envelope>[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "0[\r][\n]"
 [2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"

您可以在此处找到内容类型为text/xml registry resource

的已定义注册表资源

[2] https://docs.wso2.com/display/ESB490/Setting+Up+Logging