阿波罗的战车
使用 JEXL,您可以在包含变量及其值的给定上下文 (JexlContext) 中评估脚本/表达式。JexlContext 公开了 'has' 和 'get' 方法,它们分别检查是否存在并获取变量的值。在您的情况下,您需要找出您的 JexlContext 是(或应该是);从那里,可以直接迭代您的变量(从您的脚本中提取)并检查它们的值(从上下文中)。请参阅: http: //commons.apache.org/proper/commons-jexl/apidocs/org/apache/commons/jexl3/JexlContext.html http://commons.apache.org/proper/commons-jexl/apidocs/org /apache/commons/jexl3/JexlScript.html例如(使用来自https://github.com/apache/commons-jexl的 JEXL 3.2 主干):/** * Collect the global variables of a script and their values from a context. * @param script the script * @param context the context * @return a map keyed by variable name of their contextual values */Map<String, Object> collectVars(JexlScript script, JexlContext context) { Set<List<String>> sls = script.getVariables(); Map<String, Object> vars = new TreeMap<String, Object>(); for(List<String> ls : sls) { // build the 'antish' name by concatenating StringBuilder strb = new StringBuilder(); for(String s : ls) { if (strb.length() > 0) { strb.append('.'); } strb.append(s); } String name = strb.toString(); vars.put(name, context.get(name)); } return vars;}@Testpublic void testStckOvrflw() throws Exception { JexlEngine jexl = new JexlBuilder().safe(false).create(); // a context with some variables JexlContext context = new MapContext(); context.set("low", 15000); context.set("high", 50000); context.set("mid", 35000); context.set("limit.low", 15042); context.set("limit.high", 35042); // an expression with 2 variables JexlScript expr = jexl.createScript("low >= 12345 && high <= 56789"); // collecting the 2 variables, low and high Map<String, Object> vars = collectVars(expr, context); Assert.assertEquals(2, vars.size()); Assert.assertEquals(15000, vars.get("low")); Assert.assertEquals(50000, vars.get("high")); expr = jexl.createScript("limit.low >= 12345 && limit.high <= 56789"); vars = collectVars(expr, context); Assert.assertEquals(2, vars.size()); Assert.assertEquals(15042, vars.get("limit.low")); Assert.assertEquals(35042, vars.get("limit.high"));}
慕码人8056858
您应该实现自己的上下文:public class ZenContext implements JexlContext { static private final Map<String, Object> reservedVars = new HashMap<String, Object>(); private final Map<String, Object> scriptDefinedVars = new HashMap<String, Object>(); static { reservedVars.put("math", java.lang.Math.class); reservedVars.put("stats", apache.commons.math3.stats.Stats); // whatever else ... } public boolean has(String name) { if (reservedVars .get(name) != null) return true; return scriptDefinedVars.get(name) != null; } public boolean get (String name) { Object value = null; if ((value = reservedVars .get(name)) != null) return value; return scriptDefinedVars.get(name); } public void set(String name, Object value) { scriptDefinedVars.set(name, value); } public Map<String, Object> getReservedVars () { return reservedVars; } public Map<String, Object> getScriptDefinedVars () { return scriptDefinedVars ; }}这样,您将拥有保留 var 名称的映射,以包含不允许脚本更改其值的对象。例如,可以从脚本设置的单独的变量映射。然后添加这些方法。public Object execute(File scriptFile) { JexlScript script = jexlEngine.createScript(scriptFile); return script.execute(this); // supply this as the context }public Object execute (String scriptText) { JexlScript script = jexlEngine.createScript(scriptText); return script.execute(this); // supply this as the context }您可以修改我在此处编写的 set 方法,以检查映射中的变量,然后再允许它们设置。但是,这不适用于本地脚本变量var greeting = 'The rain in Maine falls plainly insane';因为 local var 依赖于不同的机制,org.apache.commons.jexl3.internal.Scope,使用 getLocalVariables() 方法,它有一个错误。