[英]creating context for MVEL with different variable types
我正在使用MVEL評估算術和邏輯表達式或兩者的組合。 事實是,我事先不知道所有變量類型,而沒有為表達式本身(通過設置文件傳遞)創建非常復雜的解析方法。 我只有在瀏覽數據並更新上下文時才知道它們的類型。 例如,考慮表達式(a && b) && (c == 10) && (d < 5)
我從運算符中分離了變量並初始化了我的上下文,但是我不知道哪個是布爾值,哪個是整數。 我試圖用null
或new Object()
初始化上下文中的所有變量,但是它沒有按預期工作。 請參見下面的示例代碼:
import java.util.HashMap;
import java.util.Map;
import org.mvel2.MVEL;
public class Test {
private static Map<String, Object> context = new HashMap<String, Object>();
public static void main(String[] args){
String expression = "(a && b) && (c == 10) && (d < 5)";
context.put("a", new Object());
context.put("b", new Object());
context.put("c", new Object());
context.put("d", new Object());
//do some processing and get the right value, replacing it in the context with the right type
evaluate(expression,context); //just to try to evaluate with nothing set, crashes
context.put("a", new Boolean(true));
evaluate(expression,context);//crashes same as above
context.put("b", new Boolean(true));
evaluate(expression,context); //works. the expression is not yet true but it does not crash
context.put("c", new Integer(10));
context.put("d", new Integer(1));
evaluate(expression,context); //works. expression is true
}
private static void evaluate(String expression, Map<String,Object> context){
if((Boolean)MVEL.eval(expression, context))
System.out.println("Hooray");
else
System.out.println("Boo!");
}
}
當它崩潰時,我得到以下消息: Exception in thread "main" org.mvel2.ScriptRuntimeException: expected Boolean; but found: java.lang.Object
Exception in thread "main" org.mvel2.ScriptRuntimeException: expected Boolean; but found: java.lang.Object
如果我使用null
初始化,它會崩潰說..but found: null
我的猜測是,它在MVEL.eval()方法中確定了它應該將布爾值作為第一個變量,但是我願意找不到一致的行為。 第二個例子使我更加困惑。 請參見下面的示例代碼:
import java.util.HashMap;
import java.util.Map;
import org.mvel2.MVEL;
public class Test {
private static Map<String, Object> context = new HashMap<String, Object>();
public static void main(String[] args){
context.put("a", null);
context.put("b", null);
context.put("c", null);
String expression = "( a > b + 2 ) && ( c < a - 5 )";
evaluate(expression,context); //this time it does not crash. it evaluates correctly as false
//do some processing and get the right value, and replace it in the context
context.put("a",new Integer(25));
evaluate(expression,context); //crashes. error below
context.put("b", new Integer(20));
context.put("c", new Integer(10));
evaluate(expression,context); //evaluates correctly to true.
}
private static void evaluate(String expression, Map<String,Object> context){
if((Boolean)MVEL.eval(expression, context))
System.out.println("Hooray");
else
System.out.println("Boo!");
}
}
在第二個示例中,崩潰的錯誤消息是: Exception in thread "main" [Error: failed to subEval expression] [Near : {... ( a > b + 2 ) && ( c < a - 5 ) ....}] ^
是否可以對上下文變量進行默認初始化? 我可以使用new Boolean(false)
初始化它們,但這會影響表達式。 我必須使用嚴格輸入還是強類型輸入? 順便說一句,我找不到這些類的任何體面的文檔..任何建議,不勝感激。 謝謝。
首先,您可以要求MVEL自動獲取輸入變量。 不幸的是,MVEL不會告訴您它認為對象類型是什么。 因此,例如:
Public class MvelVarTest {
public static void main(String[] args) {
String expression = "( a > b + 2 ) && ( c < a - 5 )";
ParserContext context = new ParserContext();
Serializable compiledExpression = MVEL.compileExpression(expression, context);
//Now the context will have a list of all the inputs. Unfortunatly it does not tell you what type of Object the input is.
for (Map.Entry<String,Class> entry : context.getInputs().entrySet()) {
System.out.println("Variable name : "+entry.getKey()+", Data Type = "+entry.getValue().toString());
}
//Now, you can assign values to the data and run the expression.
Map values = new HashMap();
values.put("a",25);
values.put("b",20);
values.put("c",10);
//And we can get a boolean answer
System.out.println("Result of running formula with (a=25, b=20, c=10) = "+MVEL.executeExpression(compiledExpression,values,Boolean.class));
}
}
但是,當使用值設置HashMap時,可以只放入字符串值,而MVEL可以“自動轉換”它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.