`
chinese.darren
  • 浏览: 101480 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Rhino——一个可以在Java中操作和执行JS的框架

阅读更多

前段时间,在浏览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已经把它收归帐下,成了正规军。

  1. public class MathEval   
  2. {   
  3.     public static void main(String[] args)   
  4.     {   
  5.         Context cx = Context.enter();   
  6.         try  
  7.         {   
  8.             Scriptable scope = cx.initStandardObjects();   
  9.             String str = "9*(1+2)";   
  10.             Object result = cx.evaluateString(scope, str, null1null);   
  11.             double res = Context.toNumber(result);   
  12.             System.out.println(res);   
  13.         }   
  14.         finally  
  15.         {   
  16.             Context.exit();   
  17.         }   
  18.     }   
  19. }  

下面总结一下前段时间学习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 代码
  1. function isPrime (num)   
  2. {   
  3.     if (num <= 1) {   
  4.         print("Please enter a positive integer >= 2.")   
  5.         return false  
  6.     }   
  7.        
  8.     var prime = true  
  9.     var sqrRoot = Math.round(Math.sqrt(num))   
  10.        
  11.     for (var n = 2; prime & n <= sqrRoot; ++n) {   
  12.         prime = (num % n != 0)   
  13.     }   
  14.        
  15.     return prime   
  16. }  


如何运行呢:
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

再给个例子,脚本如下:

  1. person = {   
  2.   name:"Mike Squillace",   
  3.   age:37,   
  4.   position:"software engineer",   
  5.   getFirstName:function () {return this.name.split(" ")[0]}   
  6. }   
  7. 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 代码
  1. package co.test;   
  2.   
  3. import org.mozilla.javascript.Function;   
  4.   
  5. public class JSFunction  //extends ScriptableObject   
  6. {   
  7.  private String name;    
  8.     
  9.  private Function handle;   
  10.     
  11.  public void setHandler(Function func)   
  12.  {   
  13.   this.handle = func;   
  14.  }   
  15.     
  16.  public Function getHandler()   
  17.  {   
  18.   return this.handle;   
  19.  }   
  20.   
  21.     
  22.  public JSFunction(String s)   
  23.  {   
  24.   this.name = s;   
  25.  }    
  26.     
  27.  public static void print(String s)   
  28.  {   
  29.   System.out.println(s);   
  30.  }   
  31.   
  32.  public String getName() {   
  33.   return name;   
  34.  }   
  35.  public void setName(String name) {   
  36.   this.name = name;   
  37.  }   
  38.   
  39. }   
  40.   

JSExploration.java:

java 代码
  1. package co.test;   
  2.   
  3. import java.io.FileReader;   
  4. import java.io.LineNumberReader;   
  5.   
  6. import org.mozilla.javascript.Context;   
  7. import org.mozilla.javascript.Function;   
  8. import org.mozilla.javascript.Scriptable;   
  9.   
  10. public class JSExploration   
  11. {   
  12.     private Context cx;   
  13.   
  14.     private Scriptable scope;   
  15.   
  16.     public JSExploration()   
  17.     {   
  18.         this.cx = Context.enter();   
  19.         this.scope = cx.initStandardObjects();   
  20.     }   
  21.   
  22.     public Object runJavaScript(String filename)   
  23.     {   
  24.         String jsContent = this.getJsContent(filename);   
  25.         Object result = cx.evaluateString(scope, jsContent, filename, 1null);   
  26.         return result;   
  27.     }   
  28.   
  29.     private String getJsContent(String filename)   
  30.     {   
  31.         LineNumberReader reader;   
  32.         try  
  33.         {   
  34.             reader = new LineNumberReader(new FileReader(filename));   
  35.             String s = null;   
  36.             StringBuffer sb = new StringBuffer();   
  37.             while ((s = reader.readLine()) != null)   
  38.             {   
  39.                 sb.append(s).append("\n");   
  40.             }   
  41.             return sb.toString();   
  42.         }   
  43.         catch (Exception e)   
  44.         {   
  45.             // TODO Auto-generated catch block   
  46.             e.printStackTrace();   
  47.             return null;   
  48.         }   
  49.     }   
  50.   
  51.   
  52.     public Scriptable getScope()   
  53.     {   
  54.         return scope;   
  55.     }   
  56.   
  57.     public static void main(String[] args)   
  58.     {   
  59.         String filename = System.getProperty("user.dir") + "/jsmap.js";   
  60.         JSExploration jsExploration = new JSExploration();   
  61.         Object result = jsExploration.runJavaScript(filename);   
  62.         Scriptable scope = jsExploration.getScope();   
  63.         Scriptable obj = (Scriptable) scope.get("obj", scope);   
  64.         System.out.println("obj.a == " + obj.get("a", obj));   
  65.         Scriptable b = (Scriptable) obj.get("b", obj);   
  66.         System.out.println("b[0] == " + b.get(0, b));   
  67.         Boolean flag = (Boolean) scope.get("flag", scope);   
  68.         System.out.println(flag);   
  69.   
  70.         Scriptable myobj = (Scriptable) scope.get("obj", scope);   
  71.         Boolean myflag = (Boolean) scope.get("flag", scope);   
  72.         System.out.println(myflag);   
  73.   
  74.         Scriptable jsFunction = (Scriptable) scope.get("jsFunction", scope);   
  75.         Function fc = (Function) jsFunction.get("handler", jsFunction);   
  76.         Object isPrime = fc.call(Context.getCurrentContext(), jsFunction, fc, new Object[] { "this is my test" });   
  77.     }   
  78. }   
  79.   

js脚本:jsmap.js

js 代码
  1. var swingNames = JavaImporter();   
  2.   
  3. swingNames.importPackage(Packages.java.lang);   
  4. swingNames.importPackage(Packages.co.test);   
  5.   
  6. obj = {a:1, b:['x','y']}   
  7. next = isPrime   
  8. flag = isPrime(5)   
  9. with (swingNames) {   
  10.  System.out.println("in javascript");   
  11.  JSFunction.print("in JSFunction");   
  12.   jsFunction = new JSFunction("lichunlei");   
  13.  var name = jsFunction.getName();   
  14.  System.out.println("get name from java source: " + name);   
  15.  jsFunction.setHandler(log);    
  16. }    
  17.   
  18. java.lang.System.out.println("not use swingNames");   
  19. function isPrime (num)   
  20. {   
  21.  java.lang.System.out.println("in isPrime(num)");   
  22.     if (num <= 1) {   
  23.         java.lang.System.out.println("Please enter a positive integer >= 2.")   
  24.         return false  
  25.     }   
  26.        
  27.     var prime = true  
  28.     var sqrRoot = Math.round(Math.sqrt(num))   
  29.        
  30.     for (var n = 2; prime & n <= sqrRoot; ++n) {   
  31.         prime = (num % n != 0)   
  32.     }   
  33.        
  34.     return prime   
  35. }   
  36.   
  37. function log(msg)   
  38. {   
  39.  java.lang.System.out.println("in function log: " + msg);   
  40. }   
  41.   
  42.    
分享到:
评论

相关推荐

    深入浅出Rhino:Java与JS互操作

    《深入浅出Rhino:Java与JS互操作》是一本专注于探讨如何在Java环境中使用Rhino JavaScript引擎进行交互的书籍。Rhino是Mozilla基金会开发的一个开源JavaScript解释器,它完全用Java编写,使得JavaScript能够在Java...

    java运行js脚本引擎-----rhino

    Java运行JavaScript脚本引擎Rhino是一个强大的工具,它允许Java应用程序执行JavaScript代码并利用JavaScript的灵活性和动态性。Rhino是Mozilla基金会开发的一个开源项目,它完全用Java编写,因此可以无缝集成到Java...

    Pure JS (6.2):结合 Rhino 和 Junit GUI 测试 JS

    综上所述,"Pure JS (6.2):结合 Rhino 和 Junit GUI 测试 JS" 是关于在Java环境中使用Rhino引擎进行JavaScript测试的一个话题,特别是如何通过JUnit的GUI界面来展示和管理这些测试。这涉及到了JavaScript与Java的...

    Java直接调用js文件框架rhino-1.7.9源代码

    Java直接调用js文件框架rhino-1.7.9源代码 https://github.com/mozilla/rhino/releases

    使用Rhino让java执行javascript的方法实例

    在Java中运行JavaScript代码的能力是开发跨平台应用时的一个强大工具,这使得Java开发者能够利用JavaScript的灵活性和库资源。Rhino,由Mozilla基金会开发,就是这样一个JavaScript引擎,它允许Java程序直接执行...

    效率非常快的java读取javascript,附带源码和js.jar

    这个“效率非常快的java读取javascript”很可能就是基于Rhino引擎实现的一个快速解析和执行JavaScript的示例。 Rhino的核心特性包括: 1. **快速执行**:Rhino是用Java实现的,因此它可以充分利用Java的性能优势,...

    Java直接运行JS代码

    这主要得益于Oracle公司在Java 6版本引入的一个新特性——Java Scripting API(JSR 223),它允许Java程序执行多种脚本语言,包括JavaScript。 ### 1. Java Scripting API (JSR 223) JSR 223是Java的一个标准接口...

    FF的js引擎rhino源码,java编写

    5. **脚本编写和执行**:Rhino提供了ScriptEngine接口,这是Java Scripting API (JSR 223)的一部分,使得开发者可以方便地在Java程序中执行JavaScript代码,处理脚本编写和执行的各种需求。 6. **Rhino的API**:...

    Rhino脚本引擎技术介绍

    Rhino脚本引擎是JavaScript的一个开源实现,它能够运行JavaScript风格的脚本代码,并且可以通过这个引擎调用Java语言编写的方法。Rhino脚本引擎可以嵌入Java应用程序中执行,其最大的特点是脚本的修改不需要重启Java...

    java 混淆、加密js代码

    Java混淆和加密JavaScript代码是保护Web应用程序源代码安全的重要...在Java中运行混淆和加密后的JavaScript代码,可以通过Java的脚本引擎实现。这个压缩包提供的资源可以帮助开发者实现这些功能,确保Web应用的安全。

    java实现js中eval功能

    在Java中,这可以通过编译和执行Java的`ScriptEngine`来实现,特别是`JavaScript`引擎,如`Nashorn`(在Java 8中)或`Rhino`(在更早的版本中)。以下是一个使用`Nashorn`引擎的例子: ```java import javax.script...

    java执行JavaScript代码

    从提供的文件名`TestScript.java`来看,这可能是一个包含示例代码的Java源文件,展示如何在Java中执行JavaScript。源代码可能包括创建`ScriptEngine`、编写和执行JavaScript代码、以及调用JavaScript函数的示例。 ...

    一个java的jar包可以集成到IDE中做JAVASCRIPT的测试。

    3. **创建测试框架**: 设计一个Java测试框架,该框架可以读取JavaScript测试用例,使用JavaScript引擎执行这些用例,并捕获和报告测试结果。 4. **IDE集成**: IDE如IntelliJ IDEA、Eclipse或Visual Studio Code等,...

    Pure JS (6.1):使用 Rhino Shell 和 Debugger 运行和调试 JS

    Rhino是Mozilla开发的一个开源JavaScript引擎,它允许JavaScript在Java平台上运行,而Rhino Shell则是一个命令行工具,可以用来交互式地执行JavaScript脚本。Debugger则是用于检查和优化代码的工具,这对于理解和...

    Mozilla Rhino 介绍

    Rhino项目的起源可以追溯到1997年,当时Netscape计划开发一个纯Java版本的Navigator浏览器,并因此需要一个用Java实现的JavaScript引擎——即“Javagator”。这便是Rhino的前身。最初,Rhino通过将JavaScript编译成...

    基于Java的源码-服务端JavaScript框架 RingoJS.zip

    Rhino是Mozilla基金会开发的一个JavaScript解释器,它可以嵌入到Java应用程序中,而Nashorn则是Java 8及更高版本中的一个更快的JavaScript引擎。RingoJS通过这些引擎将JavaScript代码转换为可执行的Java字节码,从而...

    Java调用javaScript代码

    例如,你可以在Java服务端定义一个接口,该接口允许在运行时加载和执行JavaScript脚本来完成特定任务,这样就能轻松地切换或更新业务逻辑,而无需重新编译和部署Java代码。 在实际项目中,这种方法可以应用于许多...

    rhino-1.7.7.1.jar(Rhino for java)

    Rhino的jar包。 Rhino 是开源的 JavaScript 引擎,是完全基于 Java 实现,几乎可以使用 JavaScript 完成 Java 所有的工作。

    Java和JavaScript库进行交互

    Java和JavaScript库之间的交互是软件开发中的一个重要主题,特别是在构建多平台应用或增强网页功能时。Java和JavaScript作为两种不同的编程语言,它们各自在特定领域有着优势:Java以其强大的后端处理能力,而...

Global site tag (gtag.js) - Google Analytics