WSO2 ESB Java中介器设置JSON上下文属性读取异常问题
问题本质说明
这个异常和属性是否成功写入消息上下文完全无关,核心是WSO2 ESB的XPath表达式解析机制,对上下文属性的类型有固定的适配规则:
- 当你在XML流程里用
$ctx:属性名这类表达式读值时,框架的XPath评估器只会对两类内容做文本提取:一类是Java原生的基本包装类型(比如你存的int类型ID能被正常读出,就是因为Integer属于这类可直接识别的类型),另一类是实现了org.apache.axiom.om.OMNode接口的XML节点类型。 - 你存入的Gson
JsonObject是第三方JSON库的自定义对象,既不是Java原生基本类型,也没有实现OMNode接口。哪怕你在Java代码里通过getProperty打印验证已经成功把值存进上下文,XPath评估器碰到这类自定义对象时,不会主动调用对象的toString()方法提取文本值,最终会判定属性值为空,这就是日志里RESPONSE_BODY读不出来的根本原因。
适配方案
- 如果需要在ESB XML配置层通过XPath读取完整JSON内容,存储时不要直接塞入JsonObject对象,将其转为标准JSON字符串后再设置为上下文属性。也就是把原来的
messageContext.setProperty("RESPONSE_BODY", json)修改为messageContext.setProperty("RESPONSE_BODY", json.toString())。这种方式存的是String类型,完全符合XPath的解析规则,后续Log中介器、XPath过滤器、路由判断表达式都能正常读取该值。 - 如果不需要在XML配置层操作整个JSON对象,可将JsonObject内的每个字段拆分为独立的单值类型属性分别存入上下文,比如分别存
RESP_NAME、RESP_AGE这类String/int类型的属性,适配ESB端的常规表达式读取逻辑,适合字段结构固定的简单场景。 - 如果需要保留JsonObject的原始对象类型,供后续Java中介器直接操作,就不要硬靠XML层的XPath读值。这类自定义对象在Java上下文里是可以正常存取的,只要跳过XML配置层的XPath读取环节,在后续流程里接自定义Java中介器,直接通过
messageContext.getProperty("RESPONSE_BODY")拿到原始JsonObject做逻辑处理即可,不要用XML里的表达式去读这类非原生对象类型的属性。
代码修正示例
修改后的mediate方法实现如下:
public boolean mediate(MessageContext messageContext) { final JsonObject json = new JsonObject(); json.addProperty("id", 0); json.addProperty("name", "tom"); json.addProperty("age", 32); messageContext.setProperty("ID", json.get("id").getAsInt()); // 转成字符串存入,适配ESB层XPath解析规则 messageContext.setProperty("RESPONSE_BODY", json.toString()); System.out.println("TESTING JSON : " + messageContext.getProperty("RESPONSE_BODY")); return true; }
修正后跑通的日志效果为:
[2020-12-09 10:35:23,434] [EI-Core] INFO - LogMediator LOGGING JSON PROPERTY = {"id":0,"name":"tom","age":32} [2020-12-09 10:35:23,434] [EI-Core] INFO - LogMediator LOGGING ID PROPERTY = 0
内容的提问来源于stack exchange,提问作者spaceghost
相关产品推荐
相关产品推荐

