Java详解ScriptEngine接口动态执行JS脚本

 更新时间:2022年08月08日 11:10:09   作者:Cavewang  
ScriptEngine是基本接口,其方法必须在本规范的每个实现中完全起作用。这些方法提供基本脚本功能。 写入这个简单接口的应用程序可以在每个实现中进行最少的修改。 它包括执行脚本的方法,以及设置和获取值的方法

大多的方法描述都来自于jdk11API帮助文档,由于是机翻,可能有些难以理解,大家多多担待

简介

首先来看一下JDK11API文档中对ScriptEngine的描述

模块 java.scripting

软件包 javax.script

Interface ScriptEngin

public interface ScriptEngine

ScriptEngine是基本接口,其方法必须在本规范的每个实现中完全起作用。

这些方法提供基本脚本功能。 写入这个简单接口的应用程序可以在每个实现中进行最少的修改。 它包括执行脚本的方法,以及设置和获取值的方法。

值是两种类型的键/值对。 第一类对包括其密钥在本说明书中保留和定义的那些或由各个实现组成。 具有保留键的对中的值具有指定的含义。

另一种类型的对包括那些创建Java语言绑定的对,这些值通常由脚本中的相应键或它们的装饰形式表示。

Eval(String script)

eval方法有多个重载,本文只介绍最常用的Eval(String script)

描述

执行指定的脚本。

实例代码

    /**
     * ScriptEngine.eval()
     */
    public void jsEngineEvalTest() {
        ScriptEngineManager sem = new ScriptEngineManager();
        //查找并为给定的扩展创建ScriptEngine。也可用getEngineByName,查找并为给定名称创建ScriptEngine 
        ScriptEngine jsEngine = sem.getEngineByExtension("js");
        try {
            jsEngine.eval("var array = [1, 2, 3, 4, 5];for (var i = 0; i < array.length; i++) {print('index:' + i + ',value:' + array[i]);}");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

执行的脚本很简单,遍历输出了一个数组

结果如下所示:

index:0,value:1
index:1,value:2
index:2,value:3
index:3,value:4
index:4,value:5

Put() and Get()

描述

void put​(String key, Object value) : 设置ScriptEngine状态中的键/值对,可以创建用于执行脚本的Java语言绑定,也可以以其他方式使用,具体取决于是否保留键。

Object get​(String key) : 检索在此引擎状态下设置的值。 该值可能是其中之一是使用设置setValue或状态的其他值ScriptEngine ,取决于实施。

实例代码

    /**
     * ScriptEngine.put() and ScriptEngine.get()
     */
    public void jsEnginePutTest(){
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        //向engine中存值
        engine.put("str", "jsEnginePutTest");
        try {
            engine.eval("var output ='' ;for (i = 0; i <= str.length; i++) {  output = str.charAt(i) + output }");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        //从engine中取值
        String name = (String) engine.get("output");
        System.out.println("被翻转后的字符串:"+name);
    }

此处的js脚本是将str字符串进行翻转操作,结果如下

被翻转后的字符串:tseTtuPenignEsj

CompiledScript

描述

通过存储编译结果的类进行扩展。 状态可以以Java类,Java类文件或脚本语言操作码的形式存储。 脚本可以重复执行而无需重新分析。

我的理解:将ScriptEngine解析一段脚本的结果存起来,方便多次调用。但是使用时要先将ScriptEngine用Compilable接口强制转换,然后调用compile(String script)方法就能返回一个CompiledScript对象,下次使用的时候调用一下CompiledScript.eval()即可,以此可以省略每次使用脚本都要重新解析一遍的过程。

实例代码

    /**
     * CompiledScript
     */
    public void compiledScriptTest(){
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        //进行强制转换
        Compilable compilable = (Compilable) engine;
        String script = "print('CompiledScriptTest')";
        try {
        	//脚本解析结果存到JSFunction中,下次使用时用jsFunction.eval()即可
            CompiledScript jsFunction = compilable.compile(script);
            jsFunction.eval();
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

此处js脚本只是进行一个简单的输出,结果如下:

CompiledScriptTest

Bindings

描述

没有找到对Bindings很准确的解释,这里写下查阅了很多码友的笔记后我的得出的结论,Bindings是一个用来存放数据的容器,它有3个层级,为Global级、Engine级和Local级,前2者通过ScriptEngine.getBindings()获得,是唯一的对象,而Local Binding由ScriptEngine.createBindings()获得,很好理解,每次都产生一个新的。Global对应到工厂,Engine对应到ScriptEngine,向这2者里面加入任何数据或者编译后的脚本执行对象,在每一份新生成的Local Binding里面都会存在。

实例代码

    /**
     * Bindings
     */
    public void jsEngineBindingsTest(){
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
        Compilable compilable = (Compilable) engine;
        Bindings bindings = engine.createBindings();
        String script = "function add(num1,num2){return num1+num2} add(a, b)";
        CompiledScript JSFunction = null;
        try {
            JSFunction = compilable.compile(script);
            //向bingdings中传入键值对
            bindings.put("a", 1);
            bindings.put("b", 2);
            //调用eval时将bindings也传入
            Object result = JSFunction.eval(bindings);
            System.out.println(result);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

此处脚本代码进行了一个简单的加法运算,结果如下:

3.0

到此这篇关于Java详解ScriptEngine接口动态执行JS脚本的文章就介绍到这了,更多相关Java ScriptEngine内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot使用GZIP压缩反回数据问题

    SpringBoot使用GZIP压缩反回数据问题

    这篇文章主要介绍了SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Java网络编程TCP实现聊天功能

    Java网络编程TCP实现聊天功能

    这篇文章主要为大家详细介绍了Java网络编程TCP实现聊天功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java实现十进制与二进制互转的示例详解

    Java实现十进制与二进制互转的示例详解

    这篇文章主要为大家详细介绍了Java如何实现十进制与二进制的互转,文中的示例代码讲解详细,对我们学习Java有一定帮助,需要的可以参考一下
    2022-11-11
  • eclipse下ini设置详情

    eclipse下ini设置详情

    这篇文章主要介绍了eclipse下ini设置详情,需要的朋友可以参考下
    2017-10-10
  • mybatis 批量将list数据插入到数据库的实现

    mybatis 批量将list数据插入到数据库的实现

    这篇文章主要介绍了mybatis 批量将list数据插入到数据库的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java 日志打印的15个好建议

    Java 日志打印的15个好建议

    这篇文章主要介绍了Java日志打印的15个好建议,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-09-09
  • idea创建的idea项目时springframework出现红色的原因和解决方法

    idea创建的idea项目时springframework出现红色的原因和解决方法

    当使用 IntelliJ IDEA 创建 Spring Framework 项目时,springframework 出现红色可能是因为相关的 Spring Framework 依赖没有正确加载或项目的配置有问题,本文给大家介绍了一些常见的原因和解决方法,需要的朋友可以参考下
    2023-09-09
  • 深入浅出分析Java抽象类和接口【功能,定义,用法,区别】

    深入浅出分析Java抽象类和接口【功能,定义,用法,区别】

    这篇文章主要介绍了Java抽象类和接口,结合实例形式深入浅出的分析了java抽象类与接口的功能功能,定义,用法及区别,需要的朋友可以参考下
    2017-08-08
  • 如何简单的理解依赖注入详解

    如何简单的理解依赖注入详解

    一直对依赖注入理解不清楚,最近突然理解了,所以下面这篇文章主要给大家介绍了关于如何简单的理解依赖注入的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-07-07
  • 携程Apollo(阿波罗)安装部署以及java整合实现

    携程Apollo(阿波罗)安装部署以及java整合实现

    这篇文章主要介绍了携程Apollo(阿波罗)安装部署以及java整合实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论