码迷,mamicode.com
首页 > 编程语言 > 详细

Java8 Nashorn实现Java调用javascript代码

时间:2018-12-26 20:23:07      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:fast   com   fun   reader   cti   map   一段   var   代码   

最近项目需要,利用java执行动态语言,首先想到的是支持js。

1.从打印Hello World开始

Java8 引入Nashorn实现javascript调用,比如使用java运行一段js实现“Hello World”打印:

package com.iflytek.research.jsdemo;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class NashornTest {
    
    public static void main(String[] args) {
        // 加载nashorn执行引擎
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            engine.eval("var str = ‘Hello World‘;"
                    + "print(str);");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
    
}

上述代码成功打印了“Hello World”, 现实场景中,script代码大多来自文件,编辑test.js

var str = ‘Hello World‘;
print(str);

将java读取方式改为从文件加载

// 加载nashorn执行引擎
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            FileReader scriptFile = new FileReader("test.js");
            engine.eval(scriptFile);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

运行后,仍然能正常打印

2.传递参数给javascript代码

可以使用SimpleBindings类来实现参数传递,改写test.js

var str = ‘Hello ‘;
print(str + name);

上述代码name变量就可以使用SimpleBindings来传递,具体实现

// 加载nashorn执行引擎
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            FileReader scriptFile = new FileReader("test.js");
            SimpleBindings simpleBindings = new SimpleBindings(); 
            simpleBindings.put("name", "Nashorn");
            engine.eval(scriptFile, simpleBindings);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

再次运行代码 打印

Hello Nashorn

这个参数在js中是全局可见的,比如将它放到函数作用域中也可以正常读取到

var good = function() {
    return name + ‘ is Good‘;
}
print(good());

打印结果

Nashorn is Good

3.指定调用的函数

在加载js文件后,可以使用Invocable接口的invokeFunction方法, 修改js文件

var good = function(name) {
    print(name + ‘ is Good‘);
}

在给函数传参直接在invokeFunction方法添加参数即可,不再需要使用SimpleBindings

public static void main(String[] args) {
        // 加载nashorn执行引擎
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            FileReader scriptFile = new FileReader("test.js");
            engine.eval(scriptFile);
            Invocable in = (Invocable) engine;
             in.invokeFunction("good","Nashorn");
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

如果要传递对象也是妥妥的

var good = function(person) {
    print( ‘name: ‘ + person.name);
}
Map<String,Object> person = new HashMap<>();
            person.put("name", "nashorn");
             in.invokeFunction("good",person);

4.获取js返回值

同样调用invokeFunction

test.js

var getPerson = function() {
    var person = {
            name : "Zhan San",
            age: 18
    }
    return person;
}
public static void main(String[] args) {
        // 加载nashorn执行引擎
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            FileReader scriptFile = new FileReader("test.js");
            engine.eval(scriptFile);
            Invocable in = (Invocable) engine;
            JSONObject personJson =(JSONObject)JSONObject.toJSON(in.invokeFunction("getPerson"));
            System.out.println(personJson.toJSONString());
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

这里json引用了fastjson包,执行之后获得结果

{"name":"Zhan San","age":18}

Java8 Nashorn实现Java调用javascript代码

标签:fast   com   fun   reader   cti   map   一段   var   代码   

原文地址:https://www.cnblogs.com/ljgeng/p/10179766.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!