WSO2 API Manager 3.2使用Script Mediator实现XML转JSON取值报错求助
WSO2 API Manager 3.2 Script Mediator XML转JSON报错问题
问题描述
我在WSO2 API Manager 3.2版本的API网关环境中,尝试通过Script Mediator中介组件实现后端XML响应报文到JSON格式的转换,核心问题是:调用Script Mediator提供的getPayloadXML()方法从XML报文中提取指定字段值时,始终抛出ReferenceError: "code" is not defined错误,多次尝试后仍无法定位根因,无法实现预期转换效果。
响应中介流配置
<sequence xmlns="http://ws.apache.org/ns/synapse" name="transform"> <script language="js"><![CDATA[ var envelope = mc.getPayloadXML()..*::fault-code.toString() var request ={"data":{"success":"true","message":"SuccessFull","faultcode":envelope}}; mc.setPayloadJSON(request); ]]></script> <log level="full"> <property name="Message" value="UpdatedMessage"/> </log> <property name="HTTP_SC" value="200" scope="axis2" /> <property name="messageType" value="application/json" scope="axis2"/> </sequence>
原始后端XML响应报文
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <wsa:MessageID>210419-BA7CF-3244</wsa:MessageID> <wsa:RelatesTo>Test123456</wsa:RelatesTo> <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To> <wsa:From> <wsa:Address>some data</wsa:Address> </wsa:From> <wsa:Action>some data</wsa:Action> </soapenv:Header> <soapenv:Body> <cbo:response xmlns:abr="url" xmlns:asic="url" client-reference1="A1" response-type="error" version="1.2"> <cbo:error> <cbo:fault-code>CBOX017</cbo:fault-code> <cbo:fault-string>User account is inactive.</cbo:fault-string> <cbo:fault-actor/> <cbo:detail/> </cbo:error> </cbo:response> </soapenv:Body> </soapenv:Envelope>
预期转换后的JSON响应
{ "data": { "success": "true", "message": "SuccessFull", "faultcode": "CBOX017" } }
注:原预期JSON中
faultcode的值未加引号,不符合JSON语法规范,上述为修正后的合法写法。
网关运行错误日志
TID: [-1234] [] [2021-04-19 16:14:41,259] ERROR {org.apache.synapse.mediators.bsf.ScriptMediator} - {api:admin--equifaxACNCheck:v1.0.0} 脚本引擎执行内联JS脚本时返回错误 com.sun.phobos.script.util.ExtendedScriptException: org.mozilla.javascript.EcmaError: ReferenceError: "code" is not defined. (<Unknown Source>#2) in <Unknown Source> at line number 2 at com.sun.phobos.script.javascript.RhinoCompiledScript.eval(RhinoCompiledScript.java:68) at javax.script.CompiledScript.eval(CompiledScript.java:92) at org.apache.synapse.mediators.bsf.ScriptMediator.mediateForInlineScript(ScriptMediator.java:395) ...(堆栈省略,核心报错为第2行代码未定义code变量) Caused by: org.mozilla.javascript.EcmaError: ReferenceError: "code" is not defined. (<Unknown Source>#2) at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3687) at org.mozilla.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3750) ...
注:堆栈细节可参考原始报错,核心问题为JS引擎解析节点名时触发语法错误。
问题根因
- 核心语法冲突:WSO2 Script Mediator使用的Rhino JS引擎会将XML节点名中的连字符
-识别为JS减法运算符,你编写的fault-code会被解析为「变量fault 减去 变量code」,由于code未定义,因此抛出ReferenceError。 - 命名空间兼容问题:原始XML中
fault-code属于自定义cbo命名空间,若未正确处理命名空间规则,也可能出现节点匹配失败的情况。
解决方案
修改Script Mediator内的JS代码,用方括号将带连字符的节点名包裹为字符串,避免被解析为运算符,同时增加节点判空逻辑提升鲁棒性:
修改后的完整中介流配置如下:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="transform"> <script language="js"><![CDATA[ // 获取XML载荷对象 var payloadXML = mc.getPayloadXML(); // 用方括号包裹带连字符的节点名,匹配任意命名空间下的fault-code节点 var faultCodeNode = payloadXML..*::['fault-code']; // 判空后取值,避免节点不存在时报错 var envelope = faultCodeNode ? faultCodeNode.toString().trim() : ''; var request = { "data": { "success": "true", "message": "SuccessFull", "faultcode": envelope } }; mc.setPayloadJSON(request); ]]></script> <log level="full"> <property name="Message" value="UpdatedMessage"/> </log> <property name="HTTP_SC" value="200" scope="axis2" /> <property name="messageType" value="application/json" scope="axis2"/> </sequence>
补充说明
- 若后续需要支持更复杂的XML转JSON逻辑,可替换为XSLT Mediator实现,语法兼容性更好,维护成本更低。
- 调试时可先添加日志输出
mc.getPayloadXML().toXMLString(),确认获取到的XML内容符合预期,避免因载荷格式不对导致匹配失败。
内容的提问来源于stack exchange,提问作者Amit Chaurasia
相关产品推荐
相关产品推荐

