最近遇到这么一个问题,如何让用户在软件中自定义函数。
举个例子,使用Java做一个小的监控系统,用户A希望CPU超过90%的时候报警,B用户希望内存超过90%的时候报警,C用户希望CPU超过90%或者内存超过80%的时候报警,D用户希望CPU超过60%且硬盘剩余小于10%的时候报警……
程序员之力有限,而用户之欲无魇。以开发追需求,如抱薪救火,不妨让用户自己定义报警的规则。
我们当然不需要为此开发一种脚本语言,我觉得JavaScript就是一种不错的语言。我们以一个单输入单输出的函数为例讲解如何使用雷锋来推倒雷峰塔……不对,用Java解析JavaScript。
首先我们新建一个Java工程(完整代码见最后)。
随后新建一个JavaScript解析器:
ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript");
加载我们的脚本:
脚本长这样:
function (x){ return x+1; };
加载之:
String js_code = readToString("scripts/user_define.js");
随后尝试处理:
try { engine.put("udfun", engine.eval(js_code)); for (int i = 1; i < 10; ++i) { engine.put("val", i); System.out.printf("f(%d)=%f\n",i,engine.eval("udfun(val);")); } } catch (ScriptException e) { e.printStackTrace(); }
可以看到我们先用了一个 engine.put("udfun", engine.eval(js_code)); 加载函数,这样避免反复解析函数,随后不停地将数值put到js引擎中去,最后输出相应的结果。
只要修改相应的JavaScript脚本就可以加载不同的配置。
软件中大多数不确定的,且执行频率不是特别高的,性能要求不高的地方都可以这样留个口子。
附上完整的Java代码:
1 package javascriptevaltest; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.io.UnsupportedEncodingException; 8 import javax.script.ScriptEngine; 9 import javax.script.ScriptEngineManager; 10 import javax.script.ScriptException; 11 12 public class JavascriptEvalTest { 13 14 public static void main(String[] args) { 15 ScriptEngineManager manager = new ScriptEngineManager(); 16 ScriptEngine engine = manager.getEngineByName("javascript"); 17 18 String js_code = readToString("scripts/user_define.js"); 19 try { 20 engine.put("udfun", engine.eval(js_code)); 21 for (int i = 1; i < 10; ++i) { 22 engine.put("val", i); 23 System.out.printf("f(%d)=%f\n",i,engine.eval("udfun(val);")); 24 } 25 } catch (ScriptException e) { 26 e.printStackTrace(); 27 } 28 } 29 30 public static String readToString(String fileName) { 31 String encoding = "ISO-8859-1"; 32 File file = new File(fileName); 33 Long filelength = file.length(); 34 byte[] filecontent = new byte[filelength.intValue()]; 35 try { 36 FileInputStream in = new FileInputStream(file); 37 in.read(filecontent); 38 in.close(); 39 } catch (FileNotFoundException e) { 40 e.printStackTrace(); 41 } catch (IOException e) { 42 e.printStackTrace(); 43 } 44 try { 45 return new String(filecontent, encoding); 46 } catch (UnsupportedEncodingException e) { 47 System.err.println("The OS does not support " + encoding); 48 e.printStackTrace(); 49 return null; 50 } 51 } 52 53 }
JavaScript代码在上面,略。
时间: 2024-10-12 20:49:52