之前在一次机缘巧合的情况下,需要时用JAVA执行js方法,查阅了一些文档,找到了相关解决方法,这里和大家分享一下。
在JDK1.6中为我们提供了一个ScriptEngineManager类,ScriptEngineManager 为 ScriptEngine 类实现一个发现和实例化机制,还维护一个键/值对集合来存储所有 Manager 创建的引擎所共享的状态。此类使用服务提供者机制枚举所有的 ScriptEngineFactory 实现。
ScriptEngineManager 提供了一个方法,可以返回一个所有工厂实现和基于语言名称、文件扩展名和 mime 类型查找工厂的实用方法所组成的数组。
键/值对的 Bindings(即由管理器维护的 “Global Scope”)对于 ScriptEngineManager 创建的所有 ScriptEngine 实例都是可用的。Bindings 中的值通常公开于所有脚本中。

通过上面的描述,我们就应该知道了,需要时用到的类为ScriptEngineManagerScriptEngine

我们先来看一下ScriptEngineManager

构造方法如下:

方法名 说明
ScriptEngineManager() 如果调用者可访问线程上下文 ClassLoader,则调用此构造方法的效果与调用 ScriptEngineManager(Thread.currentThread().getContextClassLoader()) 相同
ScriptEngineManager(ClassLoader loader) 此构造方法使用服务调用者机制加载对于给定 ClassLoader 可见的 ScriptEngineFactory 实现

方法摘要如下:

返回值 方法名 说明
Object get(String key) 获取 Global Scope 中指定键的值
Bindings getBindings() getBindings
ScriptEngine getEngineByExtension(String extension) 查找并创建一个给定扩展的 ScriptEngine
ScriptEngine getEngineByMimeType(String mimeType) 查找并创建一个给定 mime 类型的 ScriptEngine
ScriptEngine getEngineByName(String shortName) 查找并创建一个给定名称的 ScriptEngine
List<ScriptEngineFactory> getEngineFactories() 返回一个数组,该数组的元素是发现机制找到的所有 ScriptEngineFactory 类的实例
void put(String key, Object value) 设置 Global Scope 中指定的键/值对
void registerEngineExtension(String extension, ScriptEngineFactory factory) 注册一个 ScriptEngineFactory 来处理扩展
void registerEngineMimeType(String type, ScriptEngineFactory factory) 注册一个 ScriptEngineFactory 来处理 mime 类型。
void registerEngineName(String name, ScriptEngineFactory factory) 注册一个ScriptEngineFactory 来处理语言名称
void setBindings(Bindings bindings) setBindings 存储 globalScope 字段中的指定 Bindings

我们首先来看一下,JDK为我们提供了哪些可用的脚本引擎工厂,写一段代码测试一下:

@Test
public void getScriptEngineFactory()
{ScriptEngineManager manager = new ScriptEngineManager();List<ScriptEngineFactory> factories = manager.getEngineFactories();for (ScriptEngineFactory factory : factories){System.out.println(factory.getNames());}
}

运行结果如下:

[nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

通过控制台输出的结果,我们知道JDK已经为我们实现了js相关的脚本引擎,我们直接使用就可以了,解决了引擎的问题,下面我们再来看看脚本引擎如何使用,这就需要ScriptEngine了。

ScriptEngine 是基础接口,该接口的方法在此规范的每个实现中都必须具有完整的功能。
这些方法提供基本的脚本功能。为这个简单接口编写的应用程序应该对每个实现稍做修改就能够运行。这包括执行脚本的方法,以及设置和获取值的方法。
这些值是两种类型的键/值对。组成第一种类型的键/值对中的键是此规范或个别实现中保留和定义的键。包含保留键的键/值对中的值具有指定的含义。
另一种类型由那些创建 Java 语言 Bindings 的键/值对组成,值通常通过相应键或其装饰的形式用脚本表示。

方法摘要如下:

返回值 方法名 说明
Bindings createBindings() 返回一个未初始化的 Bindings
Object eval(Reader reader) 除了脚本的源是以 Reader 形式提供的外,与 eval(String) 相同
Object eval(Reader reader, Bindings n) 除了脚本的源是以 Reader 形式提供的外,与 eval(String, Bindings) 相同
Object eval(Reader reader, ScriptContext context) 与 eval(String, ScriptContext) 相同,其中脚本的源是从 Reader 读取的
Object eval(String script) 执行指定的脚本
Object eval(String script, Bindings n) 执行脚本,脚本执行期间使用 Bindings 参数作为 ScriptEngine 的 ENGINE_SCOPE Bindings
Object eval(String script, ScriptContext context) 立即执行脚本,该脚本的源是作为第一个参数传递的 String
Object get(String key) 获取在此引擎的状态中设置的值
Bindings getBindings(int scope) 返回指定值的范围
ScriptContext getContext() 返回 ScriptEngine 的默认 ScriptContext,在没有指定 ScriptContext 时,该 ScriptEngine 的 Bindings、Reader 和 Writer 被用于脚本执行
ScriptEngineFactory getFactory() 返回此 ScriptEngine 所属的类的 ScriptEngineFactory
void put(String key, Object value) 设置 ScriptEngine 的状态中的键/值对,它创建一个将在脚本执行中使用或者以其他方式使用的 Java Language Binding,具体取决于该键是否被保留
void setBindings(Bindings bindings, int scope) 设置将由脚本使用的指定值的范围。
void setContext(ScriptContext context) 设置 ScriptEngine 的默认 ScriptContext,在没有指定 ScriptContext 时,该 ScriptEngine 的 Bindings、Reader 和 Writer 被用于脚本执行

下面我们通过代码来演示具体的使用方法

首先我们先来看一下如何执行一段简单的js表达式:

@Test
public void invokeExpression() throws ScriptException
{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "1 + 2";Integer result = (Integer) engine.eval(js);System.out.println(result);
}

通过这段代码,我们很容易的就实现了java执行js的一段表达式。
在java中,我们不仅可以运行js的表达式,我们还可以执行js函数

@Test
public void invokeFunction() throws ScriptException, NoSuchMethodException
{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "function welcom(){return 'welcom';}";engine.eval(js);Invocable invocable = (Invocable) engine;String result = (String) invocable.invokeFunction("welcom");System.out.println(result);
}

这里我们用到了Invocable接口,Invocable由 ScriptEngines 实现的可选接口,该 ScriptEngines 的方法允许在以前执行过的脚本中调用程序。当然啦,我们不仅能执行函数,还可以传递参数:

@Testpublic void invokeFunctionWithParam() throws ScriptException, NoSuchMethodException
{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "function welcom(name){return 'welcom ' + name;}";engine.eval(js);Invocable invocable = (Invocable) engine;String result = (String) invocable.invokeFunction("welcom", "jianggujin");System.out.println(result);
}

除此之外,我们还可以将java对象注入到js代码中运行:

@Test
public void inject() throws ScriptException, NoSuchMethodException
{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");Date date = new Date();System.out.println(date.getTime());engine.put("date", date);String js = "function getTime(){return date.getTime();}";engine.eval(js);Invocable invocable = (Invocable) engine;Long result = (Long) invocable.invokeFunction("getTime");System.out.println(result);
}

是不是很神奇呢?下面再介绍一种更神奇的,java通过线程启动js函数:

public void runThread() throws ScriptException, NoSuchMethodException
{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");engine.put("out", System.out);String js = "var obj=new Object();obj.run=function(){out.println('thread...')}";engine.eval(js);Object obj = engine.get("obj");Invocable inv = (Invocable) engine;Runnable r = inv.getInterface(obj, Runnable.class);Thread t = new Thread(r);t.start();
}

好了,到这里java运行js的方法已经介绍的差不多了,下面贴出完整的测试代码:

import java.util.Date;
import java.util.List;import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;/*** 运行javascript* * @author jianggujin**/
public class RunJavascript
{public void getScriptEngineFactory(){ScriptEngineManager manager = new ScriptEngineManager();List<ScriptEngineFactory> factories = manager.getEngineFactories();for (ScriptEngineFactory factory : factories){System.out.println(factory.getNames());}}public void invokeExpression() throws ScriptException{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "1 + 2";Integer result = (Integer) engine.eval(js);System.out.println(result);}public void invokeFunction() throws ScriptException, NoSuchMethodException{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "function welcom(){return 'welcom';}";engine.eval(js);Invocable invocable = (Invocable) engine;String result = (String) invocable.invokeFunction("welcom");System.out.println(result);}public void invokeFunctionWithParam() throws ScriptException, NoSuchMethodException{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");String js = "function welcom(name){return 'welcom ' + name;}";engine.eval(js);Invocable invocable = (Invocable) engine;String result = (String) invocable.invokeFunction("welcom", "jianggujin");System.out.println(result);}public void inject() throws ScriptException, NoSuchMethodException{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");Date date = new Date();System.out.println(date.getTime());engine.put("date", date);String js = "function getTime(){return date.getTime();}";engine.eval(js);Invocable invocable = (Invocable) engine;Long result = (Long) invocable.invokeFunction("getTime");System.out.println(result);}public void runThread() throws ScriptException, NoSuchMethodException{ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("js");engine.put("out", System.out);String js = "var obj=new Object();obj.run=function(){out.println('thread...')}";engine.eval(js);Object obj = engine.get("obj");Invocable inv = (Invocable) engine;Runnable r = inv.getInterface(obj, Runnable.class);Thread t = new Thread(r);t.start();}public static void main(String[] args) throws NoSuchMethodException, ScriptException{new RunJavascript().runThread();}}

JAVA执行javascript方法相关推荐

  1. 学习笔记——JAVA执行javascript

    java执行javascript Rhion引擎 package study;import java.io.FileNotFoundException; import java.io.FileRead ...

  2. java执行JavaScript代码

    java执行JavaScript代码的方式有很多,这里讲一下使用 Mozilla 公司开发的 Rhino 实现的,该实现从 1.6开始集成到 jdk里面. 1,对象相互转化 // 获取引擎对象    ...

  3. Java执行main方法,异常为:could not find the main class.program will exit

    Java执行main方法,异常为:could not find the main class.program will exit 参考文章: (1)Java执行main方法,异常为:could not ...

  4. Java执行JavaScript代码:传参、获取变量、返回值、JSON对象

    脚本包 Java 脚本功能是在 javax.script 包中.这是一个比较小的,简单的API.脚本的出发点是 ScriptEngineManager 类,ScriptEngineManager是一个 ...

  5. 【java神操作】java竟然还可以能执行Javascript代码!!

    引入:闲着没事想研究下学校查成绩的接口,然后自己写程序查.但是查成绩首先必须登录,所以必须先研究学校网站的登录接口,抓包后发现传到后台的学号密码是经过加密的,研究其加密方法成为必经之路 发现学校网站改 ...

  6. 【Linux】shell调用Java程序main方法通过crontab定时执行

    来源:https://blog.csdn.net/coolcooldool/article/details/51775105 最近一个项目需要写一个batch定时读取文件往数据库里插入记录,第一次写, ...

  7. android 调用java类_Android中在WebView里实现Javascript调用Java类的方法

    搜索热词 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法 ...

  8. java 脚本引擎执行javascript脚本

    java脚本引擎是从JDK6.0之后添加的新功能,语法使用Rhino. public class ScriptTest {public static void main(String args[]) ...

  9. 【Java脚本引擎】脚本引擎执行JavaScript代码

    应用场景 公司有30员工,每个人工资计算方式不同.现在需要计算工资. 传统的方法:一个接口,30个实现类. 使用脚本引擎:编写一个xml文件,每人一个计算公式,使用的时候可以把公式加载到程序中,启动时 ...

最新文章

  1. 服务发现与负载均衡 dubbo zk原理
  2. [React Native] 解析JSON文件
  3. UNIX再学习 -- 用户 ID 和组 ID
  4. 我的世界1.13的服务器网站,我的世界1.13纯净版
  5. Leetcode题库 172.阶乘后的零(C实现)
  6. mysql的主从分离_Mysql的主从分离配置
  7. 上传失败 已保存至草稿_学霸的草稿纸火了,卷面整洁,网友调侃:作业都比不上这草稿本...
  8. linux+arch系统下载,Linux
  9. C++之静态成员变量和静态成员函数
  10. google search console的使用
  11. 发动机性能测试软件,发动机的性能测试方法
  12. Linux学习笔记第八周七次课(4月3日)
  13. Denoise 方法汇总
  14. 远场语音识别面临的瓶颈与挑战
  15. 官方配置要求_电脑配置不够玩赛博朋克?租电脑一个月只要百来元就能玩!
  16. 每周送新书:Python数据分析、SSM框架、Redis深度历险
  17. Python网络爬虫——爬取视频网站源视频!
  18. android 手机内存清理,安卓手机内存如何清理 安卓手机内存清理方法【介绍】
  19. HTC Vive Unity 教程
  20. 免流解密之SAOML二开

热门文章

  1. 申请计算机专业有关个人陈述吗,美国计算机博士申请个人陈述范文
  2. 设置Google浏览器在点击网站时,在新页面打开
  3. studio3T import a SQL Database to Mongodb(从mysql中导入数据到mongodb)
  4. DDA直线插补算法原理与实现(matlab)
  5. 上海财经大学本科毕业论文答辩PPT模板
  6. 工业相机SDK使用Python打开无法显示图像
  7. RFID定位原理及优劣势(优缺点)解读
  8. 深圳市龙岗职业技术学校录取分数线计算机,深圳各职校录取分数线
  9. i710750h和i510300h对比哪个好 i5 10300h和i7 10750h选哪个
  10. 网站建设需要要考虑到哪些细节