• java调用javascript :js引擎rhino


    前段时间,在浏览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 hinoExamplesrcisPrime.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(" ");   
                }   
                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);   
    }   

  • 相关阅读:
    vue 无缝无限滚动横条实现
    小程序 recycle-view 个人demo
    js 笔记
    java整理的一些面试资料
    使用js获取浏览器地址栏里的参数
    java面试题
    sql中索引不会被用到的几种情况
    常用linux命令
    shiro登录成功之后跳转原路径
    springboot 整合 mongodb实现 批量更新数据
  • 原文地址:https://www.cnblogs.com/shsgl/p/5180920.html
Copyright © 2020-2023  润新知