• 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}
    
  • 相关阅读:
    腾讯新闻评论数据爬取
    腾讯新闻评论数据爬取
    腾讯新闻评论数据爬取
    Storm系统架构以及代码结构学习
    Storm系统架构以及代码结构学习
    Storm系统架构以及代码结构学习
    网络新闻评论观点挖掘系统实现
    网络新闻评论观点挖掘系统实现
    网络新闻评论观点挖掘系统实现
    Confluence 6 配置验证码(Captcha)来防止垃圾
  • 原文地址:https://www.cnblogs.com/ljgeng/p/10179766.html
Copyright © 2020-2023  润新知