运用Rhino在Java中调用Javascript脚本
使用Rhino在Java中调用Javascript脚本转自:http://www.iteye.com/topic/87423?前段时间,在浏览javaeye论坛
使用Rhino在Java中调用Javascript脚本
转自:http://www.iteye.com/topic/87423
?
前段时间,在浏览javaeye论坛,看见有人征集如何在java中运行数学表达式。
结果方案五花八门:
1.jakarta commons JEXL.
2.Beanshell
3.Java Math Expression Parser jep
4.parse combinator jparsec
5.jdk 6.0的 script
6.利用SQL
7.自己写语法分析
如果自己写语法分析,没有个2000行估计搞不定。有人用sql来运行数学表达式,比较另类。
不过由于前段时间较深入的学习了一些java的javascript引擎,我给出的方案就是用javascript来计算了。
java中比较著名的js引擎当属mozilla开源的rhino,不过jdk6已经把它收归帐下,成了正规军。
- public?class?MathEval ??{ ??
- ????public?static?void?main(String[]?args) ??????{ ??
- ????????Context?cx?=?Context.enter(); ??????????try??
- ????????{ ??????????????Scriptable?scope?=?cx.initStandardObjects(); ??
- ????????????String?str?=?"9*(1+2)"; ??????????????Object?result?=?cx.evaluateString(scope,?str,?null,?1,?null); ??
- ????????????double?res?=?Context.toNumber(result); ??????????????System.out.println(res); ??
- ????????} ??????????finally??
- ????????{ ??????????????Context.exit(); ??
- ????????} ??????} ??
- }??
下面总结一下前段时间学习rhino的心得(给自己的程序添加脚本功能,其实是很酷的):
一:环境配置及运行js脚本:
在 http://www.mozilla.org/rhino/ 下载rhino:
把js.jar加入系统CLASSPATH中
可以以交互模式调用js解释器:
java org.mozilla.javascript.tools.shell.Main
然后您应该会看到解释器的版本号,后面跟着提示符 js>
用法如下:
比如:有一个js文件:
D:\eclipse-workshop\rhinoExample\src\isPrime.js
内容如下:
js 代码
- function?isPrime?(num) ??{ ??
- ????if?(num?<=?1)?{ ??????????print("Please?enter?a?positive?integer?>=?2.") ??
- ????????return?false??????} ??
- ???? ??????var?prime?=?true??
- ????var?sqrRoot?=?Math.round(Math.sqrt(num)) ?????? ??
- ????for?(var?n?=?2;?prime?&?n?<=?sqrRoot;?++n)?{ ??????????prime?=?(num?%?n?!=?0) ??
- ????} ?????? ??
- ????return?prime ??}??
如何运行呢:
1:在命令行下键入:
java org.mozilla.javascript.tools.shell.Main
2:在js〉下键入:
load("D:/eclipse-workshop/rhinoExample/src/isPrime.js");
注意:是“/”而不是“\”
3:键入:
isPrime(77);
可看见返回结果为false。
键入:
isPrime(71);返回true
再给个例子,脚本如下:
- person?=?{ ????name:"Mike?Squillace", ??
- ??age:37, ????position:"software?engineer", ??
- ??getFirstName:function?()?{return?this.name.split("?")[0]} ??} ??
- person.getFirstName()??
js产生swing的例子:
load("D:/eclipse-workshop/rhinoExample/src/SwingApplication.js");
怎么样?看见效果没?是不是很强悍?其中SwingApplication.js是rhnio自带的例子。
Rhino还有一个js脚本的调试器:
Rhino JavaScript Debugger:
java org.mozilla.javascript.tools.debugger.Main [options] [filename.js] [script-arguments]
只须运行java org.mozilla.javascript.tools.debugger.Main,就可以看到调试器的界面了。
为了加快js文件运行的速度,可以把它编译为class文件:
compile:
java org.mozilla.javascript.tools.jsc.Main D:/eclipse-workshop/rhinoExample/src/FirstCompile.js
编译产生FirstCompile.class文件
在D:/eclipse-workshop/rhinoExample/src/下运行该class文件:
java FirstCompile
二:在实际应用中不可避免的需要遇到java代码如何和javascript脚本相互访问的问题:
这是一个最简单的例子:(liveConnect.js是rhnio自带的例子):
load("D:/eclipse-workshop/rhinoExample/src/liveConnect.js");
在给个复杂点的例子, 没有什么逻辑,纯技术展示,呵呵:
JSFunction.java:
java 代码
- package?co.test; ????
- import?org.mozilla.javascript.Function; ????
- public?class?JSFunction??//extends?ScriptableObject ??{ ??
- ?private?String?name;? ??? ??
- ?private?Function?handle; ??? ??
- ?public?void?setHandler(Function?func) ???{ ??
- ??this.handle?=?func; ???} ??
- ? ???public?Function?getHandler() ??
- ?{ ????return?this.handle; ??
- ?} ????
- ? ???public?JSFunction(String?s) ??
- ?{ ????this.name?=?s; ??
- ?}? ??? ??
- ?public?static?void?print(String?s) ???{ ??
- ??System.out.println(s); ???} ??
- ???public?String?getName()?{ ??
- ??return?name; ???} ??
- ?public?void?setName(String?name)?{ ????this.name?=?name; ??
- ?} ????
- } ????
JSExploration.java:
java 代码
- package?co.test; ????
- import?java.io.FileReader; ??import?java.io.LineNumberReader; ??
- ??import?org.mozilla.javascript.Context; ??
- import?org.mozilla.javascript.Function; ??import?org.mozilla.javascript.Scriptable; ??
- ??public?class?JSExploration ??
- { ??????private?Context?cx; ??
- ??????private?Scriptable?scope; ??
- ??????public?JSExploration() ??
- ????{ ??????????this.cx?=?Context.enter(); ??
- ????????this.scope?=?cx.initStandardObjects(); ??????} ??
- ??????public?Object?runJavaScript(String?filename) ??
- ????{ ??????????String?jsContent?=?this.getJsContent(filename); ??
- ????????Object?result?=?cx.evaluateString(scope,?jsContent,?filename,?1,?null); ??????????return?result; ??
- ????} ????
- ????private?String?getJsContent(String?filename) ??????{ ??
- ????????LineNumberReader?reader; ??????????try??
- ????????{ ??????????????reader?=?new?LineNumberReader(new?FileReader(filename)); ??
- ????????????String?s?=?null; ??????????????StringBuffer?sb?=?new?StringBuffer(); ??
- ????????????while?((s?=?reader.readLine())?!=?null) ??????????????{ ??
- ????????????????sb.append(s).append("\n"); ??????????????} ??
- ????????????return?sb.toString(); ??????????} ??
- ????????catch?(Exception?e) ??????????{ ??
- ????????????//?TODO?Auto-generated?catch?block ??????????????e.printStackTrace(); ??
- ????????????return?null; ??????????} ??
- ????} ????
- ??????public?Scriptable?getScope() ??
- ????{ ??????????return?scope; ??
- ????} ????
- ????public?static?void?main(String[]?args) ??????{ ??
- ????????String?filename?=?System.getProperty("user.dir")?+?"/jsmap.js"; ??????????JSExploration?jsExploration?=?new?JSExploration(); ??
- ????????Object?result?=?jsExploration.runJavaScript(filename); ??????????Scriptable?scope?=?jsExploration.getScope(); ??
- ????????Scriptable?obj?=?(Scriptable)?scope.get("obj",?scope); ??????????System.out.println("obj.a?==?"?+?obj.get("a",?obj)); ??
- ????????Scriptable?b?=?(Scriptable)?obj.get("b",?obj); ??????????System.out.println("b[0]?==?"?+?b.get(0,?b)); ??
- ????????Boolean?flag?=?(Boolean)?scope.get("flag",?scope); ??????????System.out.println(flag); ??
- ??????????Scriptable?myobj?=?(Scriptable)?scope.get("obj",?scope); ??
- ????????Boolean?myflag?=?(Boolean)?scope.get("flag",?scope); ??????????System.out.println(myflag); ??
- ??????????Scriptable?jsFunction?=?(Scriptable)?scope.get("jsFunction",?scope); ??
- ????????Function?fc?=?(Function)?jsFunction.get("handler",?jsFunction); ??????????Object?isPrime?=?fc.call(Context.getCurrentContext(),?jsFunction,?fc,?new?Object[]?{?"this?is?my?test"?}); ??
- ????} ??} ??
- ??
js脚本:jsmap.js
js 代码
- var?swingNames?=?JavaImporter(); ????
- swingNames.importPackage(Packages.java.lang); ??swingNames.importPackage(Packages.co.test); ??
- ??obj?=?{a:1,?b:['x','y']} ??
- next?=?isPrime ??flag?=?isPrime(5) ??
- with?(swingNames)?{ ???System.out.println("in?javascript"); ??
- ?JSFunction.print("in?JSFunction"); ????jsFunction?=?new?JSFunction("lichunlei"); ??
- ?var?name?=?jsFunction.getName(); ???System.out.println("get?name?from?java?source:?"?+?name); ??
- ?jsFunction.setHandler(log);? ??}? ??
- ??java.lang.System.out.println("not?use?swingNames"); ??
- function?isPrime?(num) ??{ ??
- ?java.lang.System.out.println("in?isPrime(num)"); ??????if?(num?<=?1)?{ ??
- ????????java.lang.System.out.println("Please?enter?a?positive?integer?>=?2.") ??????????return?false??
- ????} ?????? ??
- ????var?prime?=?true??????var?sqrRoot?=?Math.round(Math.sqrt(num)) ??
- ???? ??????for?(var?n?=?2;?prime?&?n?<=?sqrRoot;?++n)?{ ??
- ????????prime?=?(num?%?n?!=?0) ??????} ??
- ???? ??????return?prime ??
- } ????
- function?log(msg) ??{ ??
- ?java.lang.System.out.println("in?function?log:?"?+?msg); ??} ??
- ??? ??
?
js 代码
?
java 代码声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。