`
esidemayi
  • 浏览: 1371 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Java中如何使用动态语言 -javascript

阅读更多
Java SE6加入了对JSR223的实现,
JSR223旨在定义一个统一的规范,使得java应用程序可以通过一套固定的接口定义与各个脚本引擎交互,从而达到java平台上调用各个脚本语言的目的。接口定义在javax.script下面。从而使是java语言可以执行javascript,ruby,python等动态语言。其中javascript的解析引擎是使用Mozilla Rhino不过是经过修改的。Mozilla Rhino是一个开源的java实现javascript的项目,jdk6中引入了Rhino1.6R2 版本,有了java对javascript的实现,对于java开发人员来说是一个非常便利事情。
下面将介绍如何在java代码中使用javascript。相关的实现在javax.script 包下面。
定义了 Invocable ScriptEngine ScriptEngineFactory Bindings ScriptContext
这5个主要接口。
下面主要介绍这几个接口的使用
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("javascript");
try {
     engine.eval("print ('Hello')");
} catch (ScriptException e) {}
上面一段是非常简单的实现。就是在console 上打出一个Hello。

 其中ScriptEngineManager 是驱动管理器,通过sun.misc.service 查找注册的脚本语言。
    List<ScriptEngineFactory> list = factory.getEngineFactories();
    for(ScriptEngineFactory engineFactory:list){
       System.out.println(engineFactory.getEngineName());
    }
Mozilla Rhino
通过getEngineFactories() 可以返回当前已经注册的脚本引擎。如果机器上没有安装ruby等启动动态语言,那些将只返回 Mozilla Rhino。

 ScriptEngine engine = factory.getEngineByName("javascript");
这段一看就明白获取javascript 的引擎,其实写成factory.getEngineByName("js")
name =[js,rhino,JavaScript,javascript,ECMAScript,ecmascript] 效果是一样的。可以通过上面提到的ScriptEngineFactory 中得到名称列表。

ScriptEngine 接口提供了
public void setContext(ScriptContext context);
public void setBindings(Bindings bindings, int scope);
public Bindings getBindings(int scope);
public Bindings createBindings();
public ScriptContext getContext();
public Object get(String key);
public void put(String key, Object value);
public Object eval(...)

其中 ScriptContext,和 Bindings 只是作为一个属性集合,并不存在其它的含义,只是一种传值的工具。
ScriptEngineManager factory = new ScriptEngineManager();
中提供的一个factory.put(key, value);
这个put 进去的所有值将作为ScriptContext.GLOBAL_SCOPE。
context.getAttribute(key, ScriptContext.ENGINE_SCOPE) 将获取不到value。
如果是context.getAttribute(key, ScriptContext.GLOBAL_SCOPE) 将可以获取的。

每一个新构建出来的ScriptEngine 都会有自己独立的ScriptContext ,同时这个ScriptContext将继承ScriptEngineManager里植入的key-value值。如果在Engine 中修改Context 里面的值 需要使用ScriptContext.ENGINE_SCOPE ,如果使用ScriptContext.GLOBAL_SCOPE 将会把全局变量修改掉:
如下例子:
ScriptEngineManager factory = new ScriptEngineManager();
factory.put("msg", "my=GLOBAL_SCOPE");
{
ScriptEngine engine1 = factory.getEngineByName("javascript");
ScriptContext context1 = engine1.getContext();
context1.setAttribute("msg", "my=ENGINE_SCOPE", ScriptContext.ENGINE_SCOPE);
try {
engine1.eval("println (msg)");
} catch (ScriptException e) {
}
}
{
ScriptEngine engine2 = factory.getEngineByName("javascript");
try {
engine2.eval("println (msg)");
} catch (ScriptException e) {
}
}
console 中出现的是:
my=ENGINE_SCOPE
my=GLOBAL_SCOPE

如果将context1.setAttribute("msg", "my=ENGINE_SCOPE", ScriptContext.GLOBAL_SCOPE); 改成这样
console 中出现的是:

my=ENGINE_SCOPE
my=ENGINE_SCOPE



 接口Invocable
这个接口非常有用,可以是java接口类与动态语言的方法合并,实现像调用java 方法一样调用动态语言的方法。

首先 声明一个简单的java接口
public interface JavaInterface {
    public void printlnMessage(String msg);
}
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("javascript");
String script = "function printlnMessage(msg){println(msg);}";
engine.eval(script);
Invocable inv = (Invocable)engine;
JavaInterface i = inv.getInterface(JavaInterface.class);
i.printlnMessage("my-JavaInterface");

如上就可以直接通过调用JavaInterface 就可以实现printlnMessage


 同时还有一个非常重要的特性是,动态语言中可以直接实现java对象

public class JavaContext {
   private List<String> list = new ArrayList<String>();
   public void put(String msg){
     list.add(msg);
   }
   public List<String> get(){
     return list;
   }
}
这个是一个简单的java类
同样在上面一段代码做一些简单的修改:
public interface JavaInterface {
    public void printlnMessage(String msg);
    public JavaContext getJavaContext();
}
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("javascript");
engine.put("javaContext", new JavaContext());
String script = "function printlnMessage(msg){javaContext.put(msg);} function getJavaContext(){return javaContext}";
engine.eval(script);
Invocable inv = (Invocable)engine;
JavaInterface i = inv.getInterface(JavaInterface.class);
i.printlnMessage("my-JavaInterface1");
i.printlnMessage("my-JavaInterface2");
for(String s:i.getJavaContext().get()){
System.out.println(s);
}
最后在console中输出:
my-JavaInterface1
my-JavaInterface2

分享到:
评论

相关推荐

    java-javascript-graalvm-源码.rar

    学习这个源码可以帮助我们理解如何在实际项目中利用 GraalVM 构建混合语言的应用,例如在后端服务中使用 Java 逻辑,而在前端或者脚本中使用 JavaScript。 通过深入研究这个源码压缩包,开发者不仅可以增强对 Java...

    在Java中使用脚本语言JavaScript

    * 在Java中使用脚本语言JavaScript。 * * @author LeiWen@FansUnion.cn,http://FansUnion.cn, * http://blog.csdn.net/FansUnion * * QQ:240370818 参考资料:...

    itwill_java_oracle_javascript-master_java_javascript_

    【标题】"itwill_java_oracle_javascript-master_java_javascript_" 涉及的主要知识点是Java编程语言、Oracle数据库管理和JavaScript脚本语言。这个项目可能是关于如何在Java和JavaScript环境中集成和使用Oracle...

    Java语言-动态编译代码并热加载类

    然而,这里标签中提到的"js热加载"可能是指JavaScript与Java的交互,比如使用JavaScript引擎如Nashorn(Java 8)或GraalVM在Java应用中执行JavaScript代码,并实现在运行时更新JavaScript逻辑。尽管Nashorn在Java 15...

    graalvm-ce-java11-linux-amd64-21.0.0.2.tar.gz

    GraalVM,全称为"Grand Global Virtual Machine",是由Oracle Labs研发的一款高性能的运行时环境,它集成了JVM(Java虚拟机)、JavaScript引擎以及Truffle框架,旨在为多种语言提供统一的高性能运行平台。...

    java源码包---java 源码 大量 实例

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    BSF(java中使用javascript)

    ### BSF(Java中使用JavaScript) #### 一、BSF简介 BSF(Bean Scripting Framework,豆脚本框架)是Apache的一个项目,它提供了一种机制,使得开发者能够在Java应用中集成各种脚本语言,如JavaScript、Python、...

    用于Kubernetes、容器等的服务健康仪表板...-Java-JavaScript-下载

    【描述】:“用于Kubernetes、容器等的服务健康仪表板...-Java-JavaScript-下载” 提到的下载部分,意味着这是一个可以部署到本地环境的应用程序,用户可以通过下载并安装来使用。这通常包括源代码,可能需要一定的...

    graalvm-ce-java11-windows-amd64-21.0.0.2.zip

    GraalVM,全称为“GraalVM”,是一款高性能的运行时环境,它集成了Java虚拟机(JVM)、JavaScript引擎、Truffle框架以及自优化的编译器,旨在为多种编程语言提供统一的运行平台。在本文中,我们将围绕graalvm-ce-...

    最新版linux graalvm-ce-java11-linux-amd64-21.3.0.tar.gz

    Linux上的GraalVM CE(Community Edition)是Oracle公司推出的一款高性能的运行时环境,它融合了Java虚拟机(JVM)、JavaScript引擎以及多种语言运行时。最新版本为"21.3.0",专为Linux平台的AMD64架构设计。这个...

    java-javascript-graalvm:使用GraalVM进行Java和JavaScript代码互操作性的示例项目

    该项目展示了如何在Java代码中使用GraalVM的`ScriptEngine` API来执行JavaScript代码。例如,你可以创建一个`ScriptEngineManager`实例,然后通过它获取`GraalJS`引擎,并执行JavaScript脚本。Java代码可以像这样与...

    Java和JavaScript.doc

    Java和JavaScript是两种不同的编程语言,虽然名字相似,但它们在设计理念、用途、执行方式和语法特性等方面有着显著的区别。 1. 开发背景与公司: - Java是由SUN Microsystems(后被Oracle收购)推出的,它是一种...

    第2章 JSP编程基础知识-JavaScript.ppt

    在JSP(JavaServer Pages)中,JavaScript常常与服务器端的Java技术结合,提供用户界面的实时反馈和增强用户体验。本章节主要介绍了JavaScript的基本概念、特点以及如何在HTML中嵌入JavaScript代码。 1. **...

    基于JavaScript和Java语言的动态网页设计方法 (1).pdf

    在本文中,我们将讨论基于JavaScript和Java语言的动态网页设计方法。该方法结合了JavaScript和Java语言的优势,提供了一种解决方案,用于提高Web页面的交互性和响应速度。 动态网页设计方法 在传统的Web开发中,...

    如何在java中使用javascript,官方指南

    在Java中使用JavaScript,官方指南主要介绍的是在Java平台标准版中嵌入和使用JavaScript脚本语言的官方指导。这通常意味着使用Java代码来调用JavaScript,并且允许JavaScript在Java应用程序内部执行。具体的知识点...

    基于jsp的连锁经营商业管理系统 - 编程语言:Java - 数据库:MySQL - 前端技术:JSP、JavaScript

    基于jsp的连锁经营商业管理系统 - 编程语言:Java - 数据库:MySQL - 前端技术:JSP、JavaScript、jquery - 后端技术:Spring、SpringMVC、MyBati.zip

    java运行js脚本引擎-----rhino

    在Java中使用Rhino,首先需要引入Rhino的库。通常,这可以通过在项目中添加`org.mozilla:rhino`的Maven依赖来实现。一旦引入,我们就可以使用`ScriptEngineManager`和`ScriptEngine`类来执行JavaScript代码。以下是...

    基于Java的mock-mail-server设计源码,支持Java, HTML, JavaScript多语言

    该项目为基于Java开发的mock-mail-server设计源码,支持Java、HTML、JavaScript等多语言环境,共包含21个文件,其中包括13个Java源文件、2个XML配置文件、1个Git忽略文件、1个Markdown文档、1个图片文件、1个属性...

    在SonarQube上使用java自定义JavaScript检测规则

    在 SonarQube 中使用 Java 开发检测规则是非常重要的,特别是在 JavaScript 项目中检测代码质量。SonarQube 提供了一个强大的平台,允许开发者使用 Java 语言开发检测规则来检测 JavaScript 代码中的错误和问题。...

    [Java] JavaScript Java Client-Server 网络应用开发 (英文版)

    [奥莱理] JavaScript Java Client-Server 网络应用开发 (英文版) [奥莱理] Client-Server Web Apps with JavaScript and Java (E-Book) ☆ 图书概要:☆ As a Java programmer, how can you tackle the ...

Global site tag (gtag.js) - Google Analytics