zoukankan      html  css  js  c++  java
  • ScriptEngineManager类(Java和JS互相调用)

    Java和Js之间的调用时基于ScriptEngineManager类,这个类是jdk8新增的:

    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.script.Bindings;
    import javax.script.Invocable;
    import javax.script.ScriptContext;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.SimpleScriptContext;
    
    import org.junit.Test;
    
    
    public class JavaScriptFunction {
    
        @Test
        public void print() throws Exception{
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            engine.eval("print('hello word!!')");
        }
        
        @Test
        public void obj() throws Exception {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            StringBuffer script = new StringBuffer();
            script.append("var obj = new Object();");
            script.append("obj.hello = function(name){print('hello, '+name);}");
            //执行这段script脚本
            engine.eval(script.toString());
            // javax.script.Invocable 是一个可选的接口
            // 检查你的script engine 接口是否已实现!
            // 注意:JavaScript engine实现了Invocable接口
            Invocable inv = (Invocable) engine;
            // 获取我们想调用那个方法所属的js对象
            Object obj = engine.get("obj");
            // 执行obj对象的名为hello的方法
            inv.invokeMethod(obj, "hello", "Script Method !!" );
        }
        
        @Test
        public void file() throws Exception{
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            engine.eval(new java.io.FileReader(new File("F:/test/test.js")));
            Invocable inv = (Invocable) engine;
            Object obj = engine.get("obj");
            inv.invokeMethod(obj, "name", "知道了" );
        }
        
        
        /**
         * 脚本变量
         * @throws Exception 
         */
        @Test
        public void scriptVar() throws Exception{
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            File file = new File("F:/test/test.txt");
            //将File对象f直接注入到js脚本中并可以作为全局变量使用
            engine.put("files", file);
            engine.eval("print(files.getPath());print(files.getName());");
        }
        
        /**
         *  使用Script实现java接口
         * @throws Exception 
         */
        public void runnableImpl() throws Exception{
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            
            // String里定义一段JavaScript代码脚本
            String script = "function run() { print('run called'); }";
            // 执行这个脚本
            engine.eval(script);
            
            // 从脚本引擎中获取Runnable接口对象(实例). 该接口方法由具有相匹配名称的脚本函数实现。
            Invocable inv = (Invocable) engine;
            // 在上面的脚本中,我们已经实现了Runnable接口的run()方法
            Runnable runnable = inv.getInterface(Runnable.class);
            
            // 启动一个线程运行上面的实现了runnable接口的script脚本
            Thread thread = new Thread(runnable);
            thread.start();
        }
        
        /**
         * 脚本引擎的多个scope
         * @throws Exception 
         */
        @Test
        public void multiScopes() throws Exception{
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("nashorn");
            // 打印全局变量 "x"
            engine.put("x", "hello word!!");
            engine.eval("print(x);");
            // 上面的代码会打印"hello word!!"
            
            // 现在,传入另一个不同的script context
            ScriptContext context = new SimpleScriptContext();
            //新的Script context绑定ScriptContext的ENGINE_SCOPE
            Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
            
            // 增加一个新变脸到新的范围 engineScope 中
            bindings.put("x", "word hello!!");
            // 执行同一个脚本 - 但这次传入一个不同的script context
            engine.eval("print(x);", bindings);
            engine.eval("print(x);");
        }
        
        
        
        public static void main(String[] args) throws Exception {
            new JavaScriptFunction().runnableImpl();
            
            List list = new ArrayList();
            list.add("1");
            list.add("1");
            list.add("1");
            
            for (Object object : list) {
                System.out.println(object);
            }
            
        }
    }

    运用Java中的封装技术将运行js脚本程序进行封装:

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    
    /**
     * 运行脚本
     * @author Ruby
     *
     */
    public class RunScript {
    
        private ScriptEngineManager manager = new ScriptEngineManager();
        private ScriptEngine engine;
        private String fileName;
        
        public RunScript(String fileName){
            engine = manager.getEngineByName("JavaScript");
            this.fileName = fileName;
        }
        
        /**
         * 设置变量
         * @param varName
         * @param obj
         */
        public void setVar(String varName, Object obj){
            engine.put(varName, obj);
        }
        
        /**
         * 启动脚本
         * @throws FileNotFoundException
         * @throws ScriptException
         */
        public void start() throws FileNotFoundException, ScriptException{
            engine.eval(new FileReader(fileName));
        }
    }

    测试

    将Logger对象注入到js对象中,那么在js文件中就可以使用java中的Logger对象了:

    public static void main(String[] args) throws Exception {
        RunScript rs = new RunScript("D:	est.js");
        rs.setVar("Logger", Logger.getLogger(ConsoleListener.class));
        rs.start();
    }

    扩展:

    使用ScriptEngineManager类判断JSON字符串是否合法:

    ScriptEngineManager sem = new ScriptEngineManager ();
            ScriptEngine se = sem.getEngineByName ("js");
            String jsonstr = "({name: 1, obj: 3,[dd]})";
            try
            {
                System.out.println (se.eval (jsonstr));
            }
            catch (ScriptException e)
            {
                System.out.println ("json格式有误");
            }

    其他方式:

    package util;
    
    import com.alibaba.fastjson.JSONException;
    import com.alibaba.fastjson.JSONObject;
    
    public class Test {
    
        public static void main(String[] args) {
            try {
                JSONObject.parse("{'a':1 'b':1}");
            } catch (JSONException e) {
                System.out.println("JSON字符串错误");
            }
        }
    
    }

  • 相关阅读:
    如何使用Total Recorder录制软件发出的声音
    火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件
    [Tools] Create a Simple CLI Tool in Node.js with CAC
    [Unit Testing] Mock a Node module's dependencies using Proxyquire
    [SCSS] Create a gradient with a Sass loop
    [Algorithm] Heap data structure and heap sort algorithm
    [Debug] Diagnose a Slow Page Using Developer Tools
    [Tools] Deploy a Monorepo to Now V2
    [PWA] Add Push Notifications to a PWA with React in Chrome and on Android
    [Algorithms] Using Dynamic Programming to Solve longest common subsequence problem
  • 原文地址:https://www.cnblogs.com/xiejn/p/11969858.html
Copyright © 2011-2022 走看看