Java8 Nashorn實現Java調用javascript代碼


最近項目需要,利用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}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM