在WSO2中设置属性时,可以以编程方式创建表达式吗?

时间:2015-05-15 16:04:21

标签: json dynamic properties wso2 expression

我有一个案例,我们在API中接受'类似JSON'的代码,一个案例存在问题,其中客户有一个数字ID作为字段名。

例如

{
  "Node1": {
     "123456": [
        {
         "Field1": "Value1",
         "Field2": "Value2"
        },
        {
         "Field1": "Value3",
         "Field2": "Value4"
        }
     ]
  }
}

现在,尝试将数组设置为属性,如果我在123456中进行硬编码

<property name="fields" expression="json-eval($.Node1.123456)" scope="default" type="STRING"></property> 

但我需要以某种方式动态设置此表达式。我引用了有问题的id作为属性值。

是否可以动态构造表达式,以便将此json设置为属性?

即。

之类的东西
 <property name="myid" value="123456"/>
 <property name="fields" expression="fn:concat('json-eval($.Node1.', get-property('myid'))" scope="default" type="STRING"></property>

是否可以将消息转换为XML并以某种方式在那里引用它并转换回json?

谢谢!

3 个答案:

答案 0 :(得分:0)

可以将Property Mediator与Script Mediator一起使用。

这是一个例子:

 <property name="payload" expression="json-eval($.)"/>
 <property name="myid" value="123456"/>
 <property name="HARDCODED" value="none"/>
 <script language="js">

    var myid = mc.getProperty("myid");

    // you can interate your payload if needed
    var payload = mc.getProperty("payload");

    // Or just make a String of it  
    var json = '{ "Node1" : { "' + myid + '": [{ "Field1": "Value1", "Field2": "Value2" }] } }';

     mc.setProperty("HARDCODED", json);

 </script>
 <payloadFactory media-type="json">
    <format>$1</format>
    <args>
       <arg evaluator="xml" expression="get-property('HARDCODED')"/>
    </args>
 </payloadFactory>

使用JavaScript,您可以直接使用它。

希望它有所帮助。

答案 1 :(得分:0)

我能够通过迂回的方式做到这一点。我必须在使用我自己的Mediator到达后修改消息。

在下面的代码中,我只是以第一次出现为例

public class MyMediator extends AbstractMediator { 
  .
  .
  public boolean mediate(MessageContext mc) {
    OMFactory factory = OMAbstractFactory.getOMFactory();

    SOAPBody b = mc.getEnvelope().getBody();
    Iterator it = b.getFirstElement().getChildrenWithLocalName("Node1");
    if(it.hasNext()){
        OMElement obj = (OMElement)it.next();
        Iterator w_it = obj.getChildElements();
        if(w_it.hasNext()){
            OMElement cfield = (OMElement)w_it.next();
            cfield.setLocalName("Order");
            .
            .
        }
       ((OMContainerEx)b).setFirstChild(obj);
     }
  }
  .
  .    
}

然后我可以获取ID并使用ID创建一个新的OMElement,并将元素重命名为有意义的元素,例如&#39; Order&#39;

所以现在我可以使用json路径引用它并将其设置为属性 例如

<property name="fields" expression="json-eval($.Order)" scope="default" type="STRING"></property>

在我的情况下,id也在Order的字段中..所以它对我来说不是问题,但是如果你需要,当你重命名节点时,你可以存储现有的名字(即12345)作为一个值,通过创建一个新的OMElement并将其添加到你的obj

&#39;((OMContainerEx)b).setFirstChild(obj);&#39;是可选的..我不关心以前的路径所以只是放弃它们。

希望这可以帮助某人(或某人回来时有更好的主意;))

答案 2 :(得分:0)

我也面临同样的problem。但是,目前我通过在JSON Payload上使用XPath来管理自己,如下所述。

<property name="htlCode" scope="default" type="STRING" value="'ALE1_LON'"/>
<property expression="fn:concat('//content[hotelcode=',$ctx:htlCode,']')" name="hotelContentExpr" scope="default" type="STRING"/>
<property expression="evaluate($ctx:hotelContentExpr)" name="hotelContent" scope="default" type="STRING"/>

无论如何,我会继续寻找解决方案,并会告诉你我是否有运气。