我正在使用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);
}