WSO2数据服务返回XML而非JSON响应问题求助
我创建了一个WSO2数据服务,用于从PostgreSQL数据库获取产品列表,配置如下:
<data name="ProductListDS" serviceNamespace="" serviceGroup="" transports="http https"> <description /> <config id="ProductListDB"> <property name="driverClassName">org.postgresql.Driver</property> <property name="url">jdbc:postgresql://localhost:5432/PRODUCTS</property> <property name="username">postgres</property> <property name="password">password123</property> </config> <operation name="QueryProductList"> <call-query href="QueryProductList" /> </operation> <resource method="GET" path="/products"> <description /> <call-query href="QueryProductList" /> </resource> <query id="QueryProductList" useConfig="ProductListDB"> <sql>SELECT service, name, amount FROM products;</sql> <result outputType="json"> { "Products": { "Product": [ { "service": "$service", "name": "$name", "amount": "$amount" } ] } } </result> </query> </data>
我在API中通过Call Mediator调用该数据服务端点,期望获取JSON数据,调用逻辑如下:
<call> <endpoint key="getProductListEndpoint"/> </call> <property expression="$body" name="responsePayload" scope="default" type="STRING"/> <log level="full"> <property expression="get-property('responsePayload')" name="Response Payload"/> </log>
但在日志中却得到了XML格式的响应:
[2023-09-02 10:15:56,147] INFO {LogMediator} - {api:project_list_api:v1.0.0} To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:542d3384-67e2-4831-bb71-c87bbdc270cc, correlation_id: ff3b8304-2e6a-4718-aca7-a88a8e222853, Direction: request, Response Payload = <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"/>, Envelope: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">soapenv:Body
</soapenv:Body></soapenv:Envelope>return (<Products xmlns="http://ws.wso2.org/dataservice/QueryProductList"><Product><amount>12000</amount><service>Wireless</service><name>1 MONTH</name></Product><Product><amount>24000</amount><service>Wireless</service><name>2 MONTH</name></Product><Product><amount>36000</amount><service>Wireless</service><name>3 MONTH</name></Product><Product><amount>20000</amount><service>Cable</service><name>1 MONTH</name></Product><Product><amount>40000</amount><service>Cable</service><name>2 MONTH</name></Product><Product><amount>60000</amount><service>Cable</service><name>3 MONTH</name></Product></Products>)
请问为何未返回预期的JSON响应?
核心原因
问题出在Call Mediator默认调用的是数据服务的SOAP操作端点,而非你配置的REST风格/products资源。数据服务的SOAP操作端点默认返回XML格式,而你定义的JSON输出规则仅绑定在REST资源上。
具体解决方法
方法1:调用REST资源端点并指定Accept头
- 调整
getProductListEndpoint的URL,指向数据服务的REST资源路径:http://<WSO2服务器地址>:<端口>/services/ProductListDS/products - 在Call Mediator前添加请求头,明确要求JSON响应:
<property name="Accept" value="application/json" scope="transport"/> <call> <endpoint key="getProductListEndpoint"/> </call>
方法2:修改数据服务操作,强制返回JSON
如果需要继续调用SOAP操作端点,可在数据服务的<operation>中指定输出格式:
<operation name="QueryProductList"> <call-query href="QueryProductList"> <with-output type="json"/> </call-query> </operation>
这样即使通过SOAP协议调用,也会返回JSON格式响应。
方法3:在API中转换XML为JSON
若无法修改数据服务或端点配置,可在Call Mediator后添加转换逻辑,将XML响应转为JSON:
<call> <endpoint key="getProductListEndpoint"/> </call> <payloadFactory media-type="json"> <format> {"Products": {"Product": $1}} </format> <args> <arg evaluator="xml" expression="//Products/Product"/> </args> </payloadFactory>
内容的提问来源于stack exchange,提问作者Kavishka Rajapakshe

