rhino-java中調用javascript

在有些狀況下須要在java裏面執行javascript,這時rhino就能夠幫忙了。mozilla的一個開源產品。 javascript

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

以前的一篇博客http://my.oschina.net/yybear/blog/101493裏面介紹的事件模塊處理程序就有利用javascript定義eventHandler,而後解釋javascript執行。 ide

先看一個簡單的應用: this

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 spa

var s ='xx';$console.print(s);
$console表示java裏面的標準輸出。

這時須要先建立一個類 .net

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了。
相關文章
相關標籤/搜索