在java中使用javascript脚本

这篇具有很好参考价值的文章主要介绍了在java中使用javascript脚本。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在java中执行js脚本,首先感觉这种操作有点无意义,但是存在即合理,作者要设计这个功能应该是有他的使用场景。java中支持使用jsp写网页,估计是这个原因才有了脚本引擎。

一、java支持的脚本语言查看

我们可以通过下面的代码查看目前支持的脚本语言:

import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import java.util.List;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) {
        // 支持的腳本引擎列表
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = manager.getEngineFactories();
        for (ScriptEngineFactory f : factories) {
            System.out.println("egine name : " + f.getEngineName() +
                    "\nengine version : " + f.getEngineVersion() +
                    "\nlanguage name : " + f.getLanguageName() +
                    "\nlanguage version : " + f.getLanguageVersion() +
                    "\nnames : " + f.getNames() +
                    "\nmime : " + f.getMimeTypes() +
                    "\nextension : " + f.getExtensions());
        }
    }
}

可以看到输出内容如下:

egine name : Oracle Nashorn
engine version : 1.8.0_161
language name : ECMAScript
language version : ECMA - 262 Edition 5.1
names : [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]
mime : [application/javascript, application/ecmascript, text/javascript, text/ecmascript]
extension : [js]

二、简单入门示例

可以看到对js的支持,下面入门一个示例demo展示如何使用该api:

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

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws ScriptException {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、从引擎管理器中获取一个引擎可以有下面三种方式:
        // getEngineByExtension()、getEngineByMimeType()、getEngineByName()。
        // 只要参数名能对上就可以,参数名称就是上面代码执行输出展示的内容
        // ScriptEngine engine = manager.getEngineByExtension("js");
        // ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // 3、执行js脚本,调用eval()方法
        String script = "var a = 1, b = 2;\n" +
                "var c = a + b;\n" +
                "print(c);";
        engine.eval(script);
    }
}
三、传递参数

上面的这种方式,参数已经在脚本中定义好了,但是在项目中,参数一般是通过方法调用时传递进去的,这时候就需要有方法将参数设置,脚本引擎是支持的,通过 put() 方法将参数传入:

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

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws ScriptException {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、设置参数
        engine.put("a", 1);
        engine.put("b", 2);

        // 4、执行脚本并获取结果输出
        String script = "function add(a, b) {\n" +
                "return a + b;\n" +
                "}\n" +
                "add(a, b);";
        Object val = engine.eval(script);
        System.out.println("sum : " + val);
    }
}

对于上面put的变量,它作用于自身engine范围内,也就是ScriptContext.ENGINE_SCOPE,put 的变量放到一个叫Bindings的Map中,可以通过 engine.getBindings(ScriptContext.ENGINE_SCOPE).get(“a”);得到put的内容。和 ENGINE_SCOPE相对,还有个ScriptContext.GLOBAL_SCOPE 作用域,其作用的变量是由同一ScriptEngineFactory创建的所有ScriptEngine共享的全局作用域。也可以将上面的代码调整为如下形式:

import javax.script.*;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws ScriptException {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、设置参数:通过Bindings设置
        Bindings bind = engine.createBindings();
        bind.put("a", 1);
        bind.put("b", 2);
        // 绑定上下文,作用域为当前引擎范围
        engine.setBindings(bind, ScriptContext.ENGINE_SCOPE);

        // 4、执行脚本并获取结果输出
        String script = "function add(a, b) {\n" +
                "return a + b;\n" +
                "}\n" +
                "add(a, b);";
        Object val = engine.eval(script);
        System.out.println("sum : " + val);
    }
}
四、动态调用方法

在项目开发过程中一般都是定义好js脚本,然后在需要运行的时候才执行对应的方法,这时候用上面的方式就不行了,需要使用Invocable的invokeFunction()方法实现定义的js函数调用,Invocable可以多次调用脚本库中的函数,使用示例如下:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws Exception {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、加载需要运行的脚本代码
        String script = "function add(a, b) {\n" +
                "return a + b;\n" +
                "}";
        engine.eval(script);

        // 4、动态调用函数并获取结果
        Invocable invocable = (Invocable) engine;
        Object result = invocable.invokeFunction("add", 1, 2);
        System.out.println("sum : " + result);
    }
}

Invocable不但可以调用js中定义的方法,还可以调用java中的接口,在接口中定义方法名,方法的实现使用js代码开发,只要保证接口中的方法名和js的方法名一致就可以调用了。
比如我定义了一个java接口如下:

/**
 * 定义一个接口,接口的实现在js中
 * @Author wangxixin
 * @Date 2023/11/10
 */
public interface JavaScriptMethod {

    /**
     * 求两个数的和
     * @param a     参数1
     * @param b     参数2
     * @return
     */
    int add(int a, int b);

    /**
     * 求两个数的最大值
     * @param a     参数1
     * @param b     参数2
     * @return
     */
    int max(int a, int b);
}

这时我要调用方法就可以改成下面这种方式:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws Exception {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、加载需要运行的脚本代码
        String script = "function add(a, b) {\n" +
                "return a + b;\n" +
                "}\n" +
                "function max(a, b) {\n" +
                "return a >= b ? a : b;\n" +
                "}";
        engine.eval(script);

        // 4、动态调用函数并获取结果
        Invocable invocable = (Invocable) engine;
        JavaScriptMethod jsMethod = invocable.getInterface(JavaScriptMethod.class);
        System.out.println("sum : " + jsMethod.add(1, 2));
        System.out.println("max : " + jsMethod.max(1, 2));
    }
}
五、脚本中使用java对象

脚本引擎不但可以在java代码中调用js开发的脚本代码,也可以将java中的对象交给脚本执行,但js是解释型语言,跟java这种编译型语言的执行性能还是有很大差距的,作为知识点还是要了解一下:

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

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws Exception {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、使用java中的对象
        String[] arr = { "kafka", "RocketMQ", "RabbitMQ" };
        engine.put("arr", arr);
        String script = "for(var i = 0; i < arr.length; i++) {\n" +
                "print(arr[i]);\n" +
                "}";
        engine.eval(script);
    }
}

脚本引擎默认是解释执行的,如果需要反复执行脚本,可以使用它的可选接口Compilable来编译执行脚本,以获得更好的性能:

import javax.script.*;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws Exception {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、编译脚本代码
        Compilable compilable = (Compilable) engine;
        String script = "function add(a, b) {\n" +
                "return a + b;\n" +
                "}";
        CompiledScript compiledScript = compilable.compile(script);
        compiledScript.eval();

        // 4、调用方法获取执行结果
        Invocable invocable = (Invocable) engine;
        Object result = invocable.invokeFunction("add", 1, 2);
        System.out.println("sum : " + result);
    }
}
六、加载外部脚本文件

上面的示例程序都是将js脚本代码嵌入到java代码中,如果要修改js代码就必须要重新打包发布项目,其实我们可以将js代码写入文件中,在代码中加载该文件,这时如果要修改js代码就不用重新编译java代码:
比如在我的E盘下有一个demo.js文件:

function add(a, b) {
  return a + b;
}

在java代码中加载该js文件并调用js中的方法:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

/**
 * 腳本语言
 * @Author xingo
 * @Date 2023/11/10
 */
public class JavaScriptDemo {

    public static void main(String[] args) throws Exception {
        // 1、创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();

        // 2、获取引擎
        ScriptEngine engine = manager.getEngineByName("js");

        // 3、加载js文件
        engine.eval(new FileReader("E:\\demo.js"));

        // 4、调用方法获取执行结果
        Invocable invocable = (Invocable) engine;
        Object result = invocable.invokeFunction("add", 1, 2);
        System.out.println("sum : " + result);
    }
}

以上总结的就是在java中脚本引擎的常用API,使用场景其实并不多。我在做项目过程中就有一个需求用到过:用户想自定义一些计算公式,这些计算公式也不复杂,都是一些加减乘除运算,在写这个需求时我就把用户的公式保存下来,然后在调用这些公式时使用了脚本引擎,用很少的代码就完成了这个功能,还是很好用的。文章来源地址https://www.toymoban.com/news/detail-763582.html

到了这里,关于在java中使用javascript脚本的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在java中使用javascript脚本

    在java中执行js脚本,首先感觉这种操作有点无意义,但是存在即合理,作者要设计这个功能应该是有他的使用场景。java中支持使用jsp写网页,估计是这个原因才有了脚本引擎。 一、java支持的脚本语言查看 我们可以通过下面的代码查看目前支持的脚本语言: 可以看到输出内

    2024年02月04日
    浏览(24)
  • [从零开发JS应用] 如何在VScode中配置Javascript环境,常见的调试方法有哪些?

    记录环境配置:本文配置的环境主要针对单独JS文件的断点调试,主要是为了调试LeetCode里面的代码。 首先在官网下载对应的版本:https://nodejs.org/en/ 开始安装,可以自定义选择安装路径。 这里 选择Add Path ,系统变量会自动设置,但是用户变量并没有自动设置,需要的话可以

    2024年02月04日
    浏览(43)
  • JavaScript 时间戳——如何在 JS 中使用 getTime() 生成时间戳

    在 JavaScript 中,时间戳通常与Unix 时间相关联。并且有不同的方法来生成这样的时间戳。 当我们使用不同的 JavaScript 方法生成时间戳时,它们会返回自 1970 年 1 月 1 日 UTC(Unix 时间)以来经过的毫秒数。 在本文中,您将学习如何使用以下方法在 JavaScript 中生成 Unix 时间戳:

    2024年02月12日
    浏览(49)
  • Node.js -- JavaScript的运行环境

    HTML : 骨架 CSS :外观 JS : 灵魂 JavaScript可以在浏览器中被执行的原因是浏览器里面都有一个JavaScript的解析引擎 浏览器 解析引擎 Chrome V8 Firefox OdinMonkey (奥丁猴) Safri JSCore IE Chakra(查克拉) 每个浏览器都内置了DOM、BOM这样的API函数。 V8引擎负责解析和执行JavaScript代码 内置

    2023年04月10日
    浏览(27)
  • 运行 Node.js 与浏览器 JavaScript

    浏览器和 Node.js 都使用 JavaScript 软件语言 - 但字面上的 运行时环境 是不同的。 Node.js(又名服务器端 JavaScript)与客户端 JavaScript 有许多相似之处。它也有很多差异。 尽管两者都使用 JavaScript 作为软件语言,但我们可以重点关注一些关键差异,这些差异使两者之间的软件开发

    2024年02月09日
    浏览(38)
  • 使用JavaScript和Vue.js框架开发的电子商务网站,实现商品展示和购物车功能

    引言: 随着互联网的快速发展和智能手机的普及,电子商务行业正迎来一个全新的时代。越来越多的消费者选择网上购物,而不再局限于传统的实体店。这种趋势不仅仅是改变了消费者的习惯购物,也给企业带来了巨大的商机。为了不断满足消费者的需求,电子商务网站需要

    2024年02月15日
    浏览(47)
  • 【云原生 | 36】Docker快速部署主流脚本语言JavaScript

    🍁 博主简介 :         🏅云计算领域优质创作者         🏅新星计划第三季python赛道第一名         🏅阿里云ACE认证高级工程师         🏅阿里云开发者社区专家博主 ✒️ 博主微信 :15575411187 💊 交流社区 :小鹏linux(个人社区)欢迎您的加入! 目录

    2024年02月02日
    浏览(36)
  • 前后端交互系统:在Node.js中运行JavaScript

    在Node.js中运行JavaScript,您需要编写适用于服务器端的代码,而不是浏览器端的代码。以下是一些示例代码,用于在Node.js中创建一个简单的HTTP服务器并在浏览器中访问它: 将上述代码保存到一个名为main.js的文件中,然后在命令行中运行 node .main.js。这将创建一个简单的HTT

    2024年02月08日
    浏览(33)
  • Java生态/Redis中如何使用Lua脚本

    Mac上安装LUA很简单,直接使用 brew 相关命令; 使用 lua -v 命令可以看到lua已经安装完毕。 创建一个test.lua文件,内容为: 执行命令: 输出为: Lua 提供了交互式编程和脚本式编程: 交互式编程:直接在命令行中输入语法,可以立即执行并查看到执行效果。 脚本是编程:编写

    2024年01月20日
    浏览(50)
  • 大数据平台开发——使用Java和Python调用Shell脚本

    大数据平台开发——使用Java和Python调用Shell脚本 在大数据平台开发中,经常会遇到需要调用Shell脚本的场景,倒不是说只能用Shell,毕竟大数据开发到头来一定是个语言无关的事情: 从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala:https://lizhiyong.blog.csdn.net/article/deta

    2023年04月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包