具有响应 wso2 调解器的对象列表
Have list of objects in response with wso2 mediator
我用 'Get' 创建了一个 rest API source.It 在输入中有参数,并使用 In 和 Out mediator 将 json 转换为 soap,然后将 soap 转换为 Json 来制作我的输出。
输出是对象列表。如果列表中有多个对象,它会正常工作。但是如果我有一个对象,我希望一个列表包含一个对象作为响应,但输出只是一个对象。并省略列表。
我的调解员有什么问题吗??
这里是JsonToSoap mediator(In mediator) :
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesJsonToSoap.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="POST"/>
<header name="Action" scope="default" value="http://tempuri.org/ILivePublisher/LivePrices"/>
<property expression="$url:instrumentIsin" name="req.var.instrumentIsin" scope="default" type="STRING"/>
<property expression="$url:since" name="req.var.since" scope="default" type="STRING"/>
<property expression="$url:to" name="req.var.to" scope="default" type="STRING"/>
<property expression="$url:interval" name="req.var.interval" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<LivePrices xmlns="http://tempuri.org/">
<instrumentIsin></instrumentIsin>
<since></since>
<to></to>
<interval></interval>
</LivePrices>
</s:Body>
</s:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('req.var.instrumentIsin')"/>
<arg evaluator="xml" expression="get-property('req.var.since')"/>
<arg evaluator="xml" expression="get-property('req.var.to')"/>
<arg evaluator="xml" expression="get-property('req.var.interval')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/soap+xml"/>
</sequence>
和SoapToJson中介者(Out mediator):
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesSoupToJson.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<m:Response xmlns:m="http://schemas.xmlsoap.org/soap/envelope/"></m:Response>
</format>
<args>
<arg evaluator="xml" expression="//s:Envelope/s:Body/t:LivePricesResponse/t:LivePricesResult/a:Close" xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://tempuri.org/"/>
</args>
</payloadFactory>
<foreach expression="//m:Response/a:Close"
xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy"
xmlns:m="http://schemas.xmlsoap.org/soap/envelope/">
<sequence>
<payloadFactory media-type="xml">
<format>
<m:LivePrices>
<m:Last></m:Last>
<m:Price></m:Price>
<m:Quantity></m:Quantity>
<m:Since></m:Since>
</m:LivePrices>
</format>
<args>
<arg evaluator="xml" expression="//a:Close/a:Last"/>
<arg evaluator="xml" expression="//a:Close/a:Price"/>
<arg evaluator="xml" expression="//a:Close/a:Quantity"/>
<arg evaluator="xml" expression="//a:Close/a:Since"/>
</args>
</payloadFactory>
</sequence>
</foreach>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
对列表中的多个对象的响应是:
{
"Response": {
"LivePrices": [
{
"Last": 2100,
"Price": 2075,
"Quantity": 29252869,
"Since": "2018-07-18T00:00:00"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:04:35"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:08:35"
}
]
}
}
并且对一个对象的响应是:
{
"Response": {
"LivePrices": {
"Last": 1903,
"Price": 1911,
"Quantity": 15345096,
"Since": "2018-07-24T00:00:00"
}
}
}
这是 wso2 esb 的预期行为,因为你正在做的是使用 属性 "application/json" 盲目地从 XML 转换为 json,所以如果你有只有多个元素,您才能获得对象列表,如果只有一个元素,那么您将获得一个对象作为响应。
您需要使用 XSLT 进行如下转换
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" indent="yes" media-type="application/json" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">{
"Response":{
"LivePrices":[
<xsl:for-each select="//LivePrices">
{
"Last":"<xsl:value-of select="//Last"/>" ,
"Price":"<xsl:value-of select="//Price"/>"
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
}
}
</xsl:template>
</xsl:stylesheet>
我用 'Get' 创建了一个 rest API source.It 在输入中有参数,并使用 In 和 Out mediator 将 json 转换为 soap,然后将 soap 转换为 Json 来制作我的输出。 输出是对象列表。如果列表中有多个对象,它会正常工作。但是如果我有一个对象,我希望一个列表包含一个对象作为响应,但输出只是一个对象。并省略列表。 我的调解员有什么问题吗??
这里是JsonToSoap mediator(In mediator) :
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesJsonToSoap.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="POST"/>
<header name="Action" scope="default" value="http://tempuri.org/ILivePublisher/LivePrices"/>
<property expression="$url:instrumentIsin" name="req.var.instrumentIsin" scope="default" type="STRING"/>
<property expression="$url:since" name="req.var.since" scope="default" type="STRING"/>
<property expression="$url:to" name="req.var.to" scope="default" type="STRING"/>
<property expression="$url:interval" name="req.var.interval" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<LivePrices xmlns="http://tempuri.org/">
<instrumentIsin></instrumentIsin>
<since></since>
<to></to>
<interval></interval>
</LivePrices>
</s:Body>
</s:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('req.var.instrumentIsin')"/>
<arg evaluator="xml" expression="get-property('req.var.since')"/>
<arg evaluator="xml" expression="get-property('req.var.to')"/>
<arg evaluator="xml" expression="get-property('req.var.interval')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/soap+xml"/>
</sequence>
和SoapToJson中介者(Out mediator):
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesSoupToJson.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<m:Response xmlns:m="http://schemas.xmlsoap.org/soap/envelope/"></m:Response>
</format>
<args>
<arg evaluator="xml" expression="//s:Envelope/s:Body/t:LivePricesResponse/t:LivePricesResult/a:Close" xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://tempuri.org/"/>
</args>
</payloadFactory>
<foreach expression="//m:Response/a:Close"
xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy"
xmlns:m="http://schemas.xmlsoap.org/soap/envelope/">
<sequence>
<payloadFactory media-type="xml">
<format>
<m:LivePrices>
<m:Last></m:Last>
<m:Price></m:Price>
<m:Quantity></m:Quantity>
<m:Since></m:Since>
</m:LivePrices>
</format>
<args>
<arg evaluator="xml" expression="//a:Close/a:Last"/>
<arg evaluator="xml" expression="//a:Close/a:Price"/>
<arg evaluator="xml" expression="//a:Close/a:Quantity"/>
<arg evaluator="xml" expression="//a:Close/a:Since"/>
</args>
</payloadFactory>
</sequence>
</foreach>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
对列表中的多个对象的响应是:
{
"Response": {
"LivePrices": [
{
"Last": 2100,
"Price": 2075,
"Quantity": 29252869,
"Since": "2018-07-18T00:00:00"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:04:35"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:08:35"
}
]
}
}
并且对一个对象的响应是:
{
"Response": {
"LivePrices": {
"Last": 1903,
"Price": 1911,
"Quantity": 15345096,
"Since": "2018-07-24T00:00:00"
}
}
}
这是 wso2 esb 的预期行为,因为你正在做的是使用 属性 "application/json" 盲目地从 XML 转换为 json,所以如果你有只有多个元素,您才能获得对象列表,如果只有一个元素,那么您将获得一个对象作为响应。 您需要使用 XSLT 进行如下转换
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" indent="yes" media-type="application/json" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">{
"Response":{
"LivePrices":[
<xsl:for-each select="//LivePrices">
{
"Last":"<xsl:value-of select="//Last"/>" ,
"Price":"<xsl:value-of select="//Price"/>"
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
}
}
</xsl:template>
</xsl:stylesheet>