• 服务端JavaScript之Rhino


    最近在看js的书,书上有介绍两个服务端js,以前只听说过node.js,第一次听说Rhino.js,并且已经集成到了jdk1.6;看来还是见的少啊!

    Rhino是一种用Java编写的javaScript解释器,能自动完成JavaScript原生类型到Java原生类型之间的相互转换,有了它,可以通过JavaScript脚本设置。查询Java属性,并调用java方法;

    先上学习的代码:

    package com.my.rhino;
    
    import java.io.FileReader;
    import java.util.List;
    
    import javax.script.Bindings;
    import javax.script.Compilable;
    import javax.script.CompiledScript;
    import javax.script.Invocable;
    import javax.script.ScriptContext;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineFactory;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    
    public class RhinoDemo {
    
        public static void main(String[] args) {
            // create ScriptEngineManager
            ScriptEngineManager manager = new ScriptEngineManager();
    
            ScriptEngine engine = manager.getEngineByName("js");
            String script = "print ('hello nm')";
            try {
                engine.eval(script);
                System.out.println();
            } catch (ScriptException e) {
                e.printStackTrace();
            }
    
            try {
                Double hour = (Double) engine.eval("var date = new Date(); date.getHours();");
                String msg;
                if (hour < 10) {
                    msg = "Good morning";
                } else if (hour < 16) {
                    msg = "Good afternoon";
                } else if (hour < 20) {
                    msg = "Good evening";
                } else {
                    msg = "Good night";
                }
                System.out.println(hour);
                System.out.println(msg);
            } catch (ScriptException e) {
                System.err.println(e);
            }
    
            try {
                FileReader reader = new FileReader("src/com/my/rhino/file.js");
                Double num = (Double) engine.eval(reader);
                System.out.println(num);
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                engine.put("a", 1);
                engine.put("b", 5);
    
                Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
                Object a = bindings.get("a");
                Object b = bindings.get("b");
                System.out.println("a = " + a);
                System.out.println("b = " + b);
    
                FileReader reader = new FileReader("src/com/my/rhino/vars.js");
                Double num = (Double) engine.eval(reader);
                System.out.println(num);
                reader.close();
    
                reader = new FileReader("src/com/my/rhino/fun.js");
                // engine.eval("function add (a, b) {c = a + b; return c; }");
                engine.eval(reader);
                Invocable jsInvoke = (Invocable) engine;
    
                Object result1 = jsInvoke.invokeFunction("add", new Object[] { 10, 5 });
                System.out.println(result1);
    
                Adder adder = jsInvoke.getInterface(Adder.class);
                int result2 = adder.add(10, 5);
                System.out.println(result2);
    
                Compilable jsCompile = (Compilable) engine;
                CompiledScript vscript = jsCompile.compile("function hi () {print ('ddddd !'); }; hi ();");
    
                for (int i = 0; i < 5; i++) {
                    vscript.eval();
                }
    
            } catch (Exception e) {
                // TODO: handle exception
            }
    
            try {
                FileReader reader = new FileReader("src/com/my/rhino/java.js");
                @SuppressWarnings("unchecked")
                List<String> num = (List<String>) engine.eval(reader);
                System.out.println();
                for (String word : num) {
                    System.out.print(word);
                }
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            List<ScriptEngineFactory> factoryList = manager.getEngineFactories();
            for (ScriptEngineFactory factory : factoryList) {
                System.out.println("=====");
                System.out.println(factory.getEngineName());
                System.out.println(factory.getEngineVersion());
                System.out.println(factory.getLanguageName());
                System.out.println(factory.getLanguageVersion());
                System.out.println(factory.getExtensions());
                System.out.println(factory.getMimeTypes());
                System.out.println(factory.getNames());
            }
        }
    }
    Rhino.java

    下面解析下:

    1、创建一个script 引擎管理器并根据名称获取需要的js引擎;以下所有操作基于这两行代码;

    // create ScriptEngineManager
    ScriptEngineManager manager = new ScriptEngineManager();
    // create a JavaScript engine
    ScriptEngine engine = manager.getEngineByName("js");

    引擎也许不止一个,可以通过以下代码输出查看;

    List<ScriptEngineFactory> factoryList = manager.getEngineFactories();
            for (ScriptEngineFactory factory : factoryList) {
                System.out.println("=====");
                System.out.println(factory.getEngineName());
                System.out.println(factory.getEngineVersion());
                System.out.println(factory.getLanguageName());
                System.out.println(factory.getLanguageVersion());
                System.out.println(factory.getExtensions());
                System.out.println(factory.getMimeTypes());
                System.out.println(factory.getNames());
            }

    获取支持的所有引擎的详细信息;我的机器输出如下:

    Mozilla Rhino
    1.7 release 3 PRERELEASE
    ECMAScript
    1.8
    [js]
    [application/javascript, application/ecmascript, text/javascript, text/ecmascript]
    [js, rhino, JavaScript, javascript, ECMAScript, ecmascript]

    2、简单输出字符串:

    String script = "print ('hello nm')";
            try {
                engine.eval(script);
                System.out.println();
            } catch (ScriptException e) {
                e.printStackTrace();
            }

    console: hello nm

    3、执行简单的js代码获取返回值:

    try {
                Double hour = (Double) engine.eval("var date = new Date(); date.getHours();");
                System.out.println(hour);
            } catch (ScriptException e) {
                System.err.println(e);
            }
    console输出当前时间的小时数:
    //13.0

    4、执行js文件里面的语句,并获取返回值:

    //java代码:  
    try { FileReader reader = new FileReader("src/com/my/rhino/file.js"); Double num = (Double) engine.eval(reader); System.out.println(num); reader.close(); } catch (Exception e) { e.printStackTrace(); }
    console ---> 18.0
    //file.js
    function add(a,b){
    return a+b; } //add(10,8); result = add(10,8); //以上两行语句皆可实现

    5、传递变量给js文件并执行js文件代码:

    //java代码
           engine.put("a", 1);
                engine.put("b", 5);
    
                Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
                Object a = bindings.get("a");
                Object b = bindings.get("b");
                System.out.println("a = " + a);
                System.out.println("b = " + b);
    
                FileReader reader = new FileReader("src/com/my/rhino/vars.js");
                Double num = (Double) engine.eval(reader);
                System.out.println(num);
                reader.close();
    //vars.js
    m = a+5; n = b+6; d = a+b;

    console---> 6.0  //只会返回最后一行的结果值

    6、java调用js中的方法:

                       
                reader = new FileReader("src/com/my/rhino/file.js");
                // engine.eval("function add (a, b) {c = a + b; return c; }");
                engine.eval(reader);
                Invocable jsInvoke = (Invocable) engine;
    
                Object result1 = jsInvoke.invokeFunction("add", new Object[] { 10, 5 });
                System.out.println(result1);
            //动态实现接口,从脚本引擎中得到Java Interface 的实例;也就是说,可以定义个一个Java接口,其实现是由脚本完成,函数名称必须相同;
                Adder adder = jsInvoke.getInterface(Adder.class);
                int result2 = adder.add(10, 5);
                System.out.println(result2);            
    package com.my.rhino;
    interface Adder {
      int add(int a, int b);
    }

    console----->  

    15.0  15

    7、编译执行

      脚本引擎默认是解释执行的,如果需要反复执行脚本,可以使用它的可选接口Compilable来编译执行脚本,以获得更好的性能,示例代码如下:
    Compilable jsCompile = (Compilable) engine;
                CompiledScript vscript = jsCompile.compile("function hi () {print ('ddddd !'); }; hi ();");
    
                for (int i = 0; i < 5; i++) {
                    vscript.eval();
                }
    //其中js代码可以从js文件中加载

    8、使用java中的对象:

        try {
                FileReader reader = new FileReader("src/com/my/rhino/java.js");
                @SuppressWarnings("unchecked")
                List<String> num = (List<String>) engine.eval(reader);
                System.out.println();
                for (String word : num) {
                    System.out.print(word);
                }
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    //java.js
    importPackage(java.util);
    //var list = java.util.ArrayList(); var list = ArrayList(); list.add('ni'); list.add(' zai'); list.add(' zuo'); list.add(' sha'); list; //var list = java.util.ArrayList();等价于importPackage(java.util); var list = ArrayList();

    9、总结:

        这都是很基本的,高级应用还需研究!

  • 相关阅读:
    【转】Visual Studio 2008中使用科学计算库GSL
    【转】[Python Tip]如何在Windows下方便地进入命令行运行程序
    【转】URL Encoding (URL转义字符)
    RDLC报表,纯文字内容,动态数据源 解决方案
    C# 数值计算
    标准库List使用注意
    VS2008 运行出现 “无法启动该程序 计算机中丢失 MSVCR90D.dll”
    数据结构在游戏中的简单应用(转)
    SQL SERVER 2005 四种排序函数
    2010.11.30
  • 原文地址:https://www.cnblogs.com/liangblog/p/5956256.html
Copyright © 2020-2023  润新知