您的位置:首页 > Web前端 > JavaScript

rhino-java中调用javascript

2013-01-14 13:15 183 查看
在有些情况下需要在java里面执行javascript,这时rhino就可以帮忙了。mozilla的一个开源产品。

官网https://developer.mozilla.org/en-US/docs/Rhino

之前的一篇博客/article/3483369.html里面介绍的事件模块处理程序就有利用javascript定义eventHandler,然后解释javascript执行。

先看一个简单的应用:

public class JavaScriptHandle {
private Scriptable global;
private int optimizationLevel = -1; // 介于-1到9之间,负值表示使用解释性执行,不会生成class
private Script script;

void handle() {
Context ctx = Context.enter();
try {
ctx.setOptimizationLevel(optimizationLevel);
if (script == null) {
script = ctx.compileString("var str = 'xx'", "firstRhino", 0, null);
}
Scriptable scope = new NativeObject();
scope.setParentScope(global);
script.exec(ctx, scope);
} finally {
Context.exit();
}
}

public static void main(String[] args) {
JavaScriptHandle jsh = new JavaScriptHandle();
jsh.handle();
}
}
还是很简单的,只有传入一个javascript的字符串就可以了。
但是更多时候我们希望在javascript里面也能调用java。比如我们希望执行这样的javascript

var s ='xx';$console.print(s);
$console表示java里面的标准输出。
这时需要先创建一个类

public class ConsoleScriptable extends ScriptableObject {
private static final long serialVersionUID = 1L;
private PrintStream printStream;

public void setPrintStream(PrintStream printStream) {
this.printStream = printStream;
}

public ConsoleScriptable() {
super();
// TODO Auto-generated constructor stub
}

@Override
public String getClassName() {
return ConsoleScriptable.class.getSimpleName();
}

@JSFunction
public static void print(Context cx, Scriptable thisObj, Object[] args, Function funObj) {
print0(thisObj, args, false);
}

@JSFunction
public static void println(Context cx, Scriptable thisObj, Object[] args, Function funObj) {
print0(thisObj, args, true);
}

private static void print0(Scriptable thisObj, Object[] args, boolean eol) {
PrintStream printStream = checkInstance(thisObj).printStream;
for (Object arg : args) {
printStream.print(Context.toString(arg));
}
if (eol) {
printStream.println();
}
}

private static ConsoleScriptable checkInstance(Scriptable obj) {
if (obj == null || !(obj instanceof ConsoleScriptable)) {
throw Context.reportRuntimeError("called on incompatible object");
}
return (ConsoleScriptable) obj;
}
这个类就是实现了$console打印字符的功能。使用时先要在rhino里面注册下这个类:
JavaScriptHandle() {
// 初始化
Context ctx = Context.enter();
global = ctx.initStandardObjects();
try {
ScriptableObject.defineClass(global, ConsoleScriptable.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
Context.exit();
}
}
使用代码:
void handle() {
Context ctx = Context.enter();
try {
ctx.setOptimizationLevel(optimizationLevel);
if (script == null) {
script = ctx.compileString("$console.print('xx');", "firstRhino", 0, null);
}
Scriptable scope = new NativeObject();
scope.setParentScope(global);
// 将$console设置标准输出
ConsoleScriptable $console = (ConsoleScriptable) ctx.newObject(scope, ConsoleScriptable.class.getSimpleName());
$console.setPrintStream(System.out);
ScriptableObject.putProperty(scope, "$console", $console); // 设置属性
script.exec(ctx, scope);
} finally {
Context.exit();
}
}
这样javascript里面就可以使用$console了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: