我正在使用JEXL评估字符串,如下所示:

'GroupName'.'ProductName'.'item'.'fields'.'duration'


其中GroupName和ProductName是String变量,其余是固定字符串。

我将上下文构建为:Map<String, Map<String, CustomClass>>最终如下所示:

组名>>产品名>> CustomClass

在评估表达式之前,我确实用空字符替换了所有单引号。

问题:当ProductName本身包含一个点时,评估不起作用。

问题:有什么方法可以告诉JEXL引擎使用自定义字符而不是点作为分隔符来评估表达式?

更新:在有关velocity的oracle文档中,它指出:不要使用'。'。属性名称中的字符。如果我理解正确的JEXL使用Velocity来解析表达式,这是否意味着没有办法克服上述问题?

问候,
文森佐

最佳答案

JEXL不使用Velocity进行解析; JEXL的灵感来自Velocity和JSP / EL(10年前)。
无论如何,如果您能够使用最新的JEXL代码(即从主干编译JEXL 3.2),则应该只能从表达式的第一个成员中删除引号。
示例测试用例如下。
干杯

public static class CustomEnzo {
    private final String name;

    public CustomEnzo(String nm) {
        this.name = nm;
    }
    public CustomEnzo getItem() {
        return this;
    }
    public String getName() {
        return name;
    }
}

@Test
public void testEnzo001() throws Exception {
    Map<String, Object> cmap = new TreeMap<>();
    Map<String, CustomEnzo> vmap = new TreeMap<>();
    vmap.put("ProductName", new CustomEnzo("000"));
    vmap.put("Product.Name", new CustomEnzo("001"));
    vmap.put("Product...Name", new CustomEnzo("002"));
    cmap.put("GroupName", vmap);
    JexlContext ctxt = new MapContext(cmap);
    JexlEngine jexl = new JexlBuilder().create();
    Object result;
    result = jexl.createExpression("GroupName.ProductName.item.name").evaluate(ctxt);
    Assert.assertEquals("000", result);
    result = jexl.createExpression("GroupName.'ProductName'.item.name").evaluate(ctxt);
    Assert.assertEquals("000", result);
    result = jexl.createExpression("GroupName.'Product.Name'.item.name").evaluate(ctxt);
    Assert.assertEquals("001", result);
    result = jexl.createExpression("GroupName.'Product...Name'.item.name").evaluate(ctxt);
    Assert.assertEquals("002", result);
    result = jexl.createExpression("GroupName.'Product...Name'.'item'.'name'").evaluate(ctxt);
    Assert.assertEquals("002", result);
}

10-02 03:04