最近遇到这么一个问题,如何让用户在软件中自定义函数。

举个例子,使用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代码:

 package javascriptevaltest;

 import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException; public class JavascriptEvalTest { public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript"); 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();
}
} public static String readToString(String fileName) {
String encoding = "ISO-8859-1";
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
return new String(filecontent, encoding);
} catch (UnsupportedEncodingException e) {
System.err.println("The OS does not support " + encoding);
e.printStackTrace();
return null;
}
} }

JavaScript代码在上面,略。

雷锋推到雷峰塔,Java implements Javascript。的更多相关文章

  1. Java 和 Javascript的关系

    写这篇文章是因为看到有人问这个问题,在想怎么会有这种SB问题,不过想想当初SB的我貌似也搞不清两者的关系,认知还是需要一个过程. 然后看到比较经典的回答有:Java 和Javascript的关系就像雷 ...

  2. Java和JavaScript中使用Json方法大全

    林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka   摘要:JSON(JavaScript Object Notation) 是一种轻量级的数 ...

  3. Java 与 JavaScript 对websocket的使用

    ebsocket,HTML5中新一代全双工通信协议.其底层仍然是http协议. 传统 HTTP 请求响应客户端服务器交互图 WebSocket 请求响应客户端服务器交互图 WebSocket 客户端支 ...

  4. javascript与java的相互调用,纯java的javascript引擎rhino(转载)

    1.下载Rhino安装包,下载地址:官网http://www.mozilla.org/rhino. 2.rhino环境配置,把解压出来的js.jar文件加入到系统的环境变量classpath 3.在命 ...

  5. Json学习总结(1)——Java和JavaScript中使用Json方法大全

    摘要:JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语 ...

  6. Java和JavaScript之间的区别

    1.简介 通过优锐课核心java学习笔记中,我们可以看到,Java和JavaScript之间的区别.我们将在本文中比较Java语言和JavaScript语言.JavaScript由Netscape开发 ...

  7. paip.java 以及JavaScript (js) 的关系以及区别

    paip.java 以及JavaScript (js) 的关系以及区别 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http:// ...

  8. WebView上实现Java与JavaScript交互

    在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用.WebView加载资源的速度并不慢,但是如果资源多了,就很慢.图片.css.js.html ...

  9. 30个深度学习库:按Python、C++、Java、JavaScript、R等10种语言分类

    30个深度学习库:按Python.C++.Java.JavaScript.R等10种语言分类 包括 Python.C++.Java.JavaScript.R.Haskell等在内的一系列编程语言的深度 ...

随机推荐

  1. ARC下需要注意的内存管理

    ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu)    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...

  2. 一个简单易懂的javascrip selection&range小案例

    在制作富文本编辑器,尤其是在制作以div元素为编辑器区域时,当鼠标离开编辑区域以后会失去焦点,失去选区,这时候就要通过selection&range来重新设置选区.[以下代码尚未考虑IE低版本 ...

  3. (简单) POJ 2387 Til the Cows Come Home,Dijkstra。

    Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...

  4. 浏览器缓存(Egret项目实例分析)

    参考文章: 浏览器缓存机制:http://web.jobbole.com/82997/ 浏览器缓存机制:http://www.cnblogs.com/skynet/archive/2012/11/28 ...

  5. storybody中页面跳转

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ if ([segue.destinationViewCont ...

  6. github 更新fork分支

    在github上开发代码的时候我们习惯的是fork一个分支,然后修改再往主分支push request,这样就可以保证多人开发, 但是随着时间的推移,自己fork的版本和主分支的版本差异越来越大; 这 ...

  7. poj1328贪心中的区间问题

    题意:给定海岛个数.雷达半径以及各海岛坐标,求能覆盖所有海岛的最小雷达数. 思路:先对每个海岛求一个区间:即能覆盖它的所有雷达的圆心所构成的区间.然后对区间排序,定义一个最右点over,依次延伸ove ...

  8. 如何成为一名优秀的UI设计师

    zccst整理 因为我自己就是一个 0 美术基础.非计算机.非艺术类科班出身,但从事视觉设计工作的同学,所以很多和题主一样大学里学着不喜欢的专业,想要转设计但又不知从何开始的朋友都来问过我类似的问题, ...

  9. WIFI机器人网

    WIFI机器人网 WIFI智能小车机器人 外网远程控制WIFI智能小车机器人(WIFI板/703N)

  10. FATFS外置UNICODE GBK双向转换码表(转)

    源:FATFS外置UNICODE GBK双向转换码表 将UtoG,GtoU双向码表放到存储卡里面实现长文件名,因为FATFS长文件名需要unicode支持, 首先将UtoG.sys,GtoU.sys两 ...