服务端JavaScript之Rhino

简介: 服务端JavaScript之Rhino

以前只听说过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());
        }
    }
}

下面解析下:

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

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

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

List 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();

相关文章
|
2月前
|
JavaScript 前端开发 中间件
JS服务端技术—Node.js知识点
本文介绍了Node.js中的几个重要模块,包括NPM、Buffer、fs模块、path模块、express模块、http模块以及mysql模块。每部分不仅提供了基础概念,还推荐了相关博文供深入学习。特别强调了express模块的使用,包括响应相关函数、中间件、Router和请求体数据解析等内容。文章还讨论了静态资源无法访问的问题及其解决方案,并总结了一些通用设置。适合Node.js初学者参考学习。
56 1
|
2月前
|
开发框架 JavaScript 前端开发
Node.js日记:客户端和服务端介绍、Node.js介绍
Node.js日记:客户端和服务端介绍、Node.js介绍
|
4月前
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息
这篇文章介绍了在Nest.js应用中使用Server-Sent Events (SSE)的技术。文章首先讨论了在特定业务场景下,为何选择SSE而不是WebSocket作为实时通信系统的实现方式。接着解释了SSE的概念,并展示了如何在Nest.js中实现SSE。文章包含客户端实现的代码示例,并以一个效果演示结束,总结SSE在Nest.js中的应用。
116 1
Nest.js 实战 (十三):实现 SSE 服务端主动向客户端推送消息
|
5月前
|
JSON JavaScript 前端开发
JS的无限可能: 前端 精妙DOM技巧至Node.js的服务端
JS的无限可能: 前端 精妙DOM技巧至Node.js的服务端
|
前端开发 JavaScript Java
使用Springboot 2.7+Websocket+js实现服务端消息实时推送
使用Springboot 2.7+Websocket+js实现服务端消息实时推送
使用Springboot 2.7+Websocket+js实现服务端消息实时推送
|
8月前
|
JavaScript 前端开发 Java
如何使用内网穿透实现远程公网访问windows node.js的服务端
如何使用内网穿透实现远程公网访问windows node.js的服务端
|
8月前
|
JavaScript 前端开发 网络协议
轻松搭建远程Node.js服务端,让你的应用在公共网络中畅行无阻!
Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation(原为 Node.js Foundation,已与 JS Foundation 合并)持有和维护,亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模。这些技术通常用于资料密集的即时应用程序。
|
JavaScript 前端开发 Python
基于Flask创建Python服务端,并调用JavaScript客户端
基于Flask创建Python服务端,并调用JavaScript客户端
109 0
|
Web App开发 JavaScript 前端开发
Node.js|服务端环境
Node.js|服务端环境
|
JavaScript 前端开发
js:Vue3.js+Express实现SSR服务端渲染
js:Vue3.js+Express实现SSR服务端渲染
424 0