欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

在 Java 中执行 JScript 代码

最编程 2024-04-23 10:52:18
...

一、pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>me.ele</groupId>
    <artifactId>test_invokeJS</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.mozilla/rhino -->
        <dependency>
            <groupId>org.mozilla</groupId>
            <artifactId>rhino</artifactId>
            <version>1.7R4</version>
        </dependency>
    </dependencies>
    
</project>

二、详细代码:

package me.ele;

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

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

/**
 * @author LZJ
 * @create 2018-09-17 20:02
 **/
public class JsInvoker {
    /**
     * 执行JS返回string
     *
     * @param js             js代码
     * @param functionName   js方法名称
     * @param functionParams js方法参数
     * @return
     */
    public String runScript(String js, String functionName, Object[] functionParams) {
        /**
         * 在导入 Rhino JavaScript 的 Java 包之后,需要创建并进入 Context。
         * 本步骤的作用在于构造 JavaScript 的运行环境,Context 中储存了脚本执行的全局环境信息
         */
        Context rhino = Context.enter();

        rhino.setOptimizationLevel(-1);
        try {
            /**
             * 在使用 Rhino 执行脚本之前,必须初始化标准对象(Object,Function 等)
             * 在 Java 中调用 JavaScript 变量就是通过该对象实现。
             * 初始化标准化对象,需要调用上下文实例的 initStandardObjects 方法,
             * 执行结果将会返回一个 Scriptable 实例化对象
             */
            Scriptable scope = rhino.initStandardObjects();

            ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(JsInvoker.this, scope));

            /**
             * (scope, string, error, num, null)
             * JavaScript 脚本的执行是使用上下文示例中的 evaluateString 方法,执行脚本字符串 string,
             * 当脚本中需要使用其它变量时,会在作用域 scope 中寻找所需要的变量,如果发生异常的话则会报告 error
             * 错误信息和所在的行号 num,正确执行结束后会返回一个 Object 对象的运行结果
             */
            rhino.evaluateString(scope, js, "MainActivity", 1, null);

            Function function = (Function) scope.get(functionName, scope);

            Object result = function.call(rhino, scope, scope, functionParams);
            if (result instanceof String) {
                return (String) result;
            } else if (result instanceof NativeJavaObject) {
                return (String) ((NativeJavaObject) result).getDefaultValue(String.class);
            } else if (result instanceof NativeObject) {
                return (String) ((NativeObject) result).getDefaultValue(String.class);
            }
            return result.toString();
        } finally {
            /**
             * 束上下文是每次使用 Rhino 结束后必须要做的工作,
             * 它将移除上下文和当前的线程并做垃圾回收
             */
            Context.exit();
        }
    }

    /**
     * @param js js代码
     *
     * @return eval方法是执行js脚本,返回脚本的返回值
     */
    public String runScriptS(String js) {
        //创建 脚本引擎管理器
        ScriptEngineManager factory = new ScriptEngineManager();
        //获取一个指定的名称的脚本引擎
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        String a = null;
        try {
            a = String.valueOf(engine.eval(js));
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return a;
    }

    /**
     * 执行无参js
     *
     * @param js js内容
     * @param functionName js方法名称
     * @return js中执行方法的返回值
     */
    public String runScript(String js, String functionName) {
        //创建 脚本引擎管理器
        ScriptEngineManager factory = new ScriptEngineManager();
        //获取一个指定的名称的脚本引擎
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        String value = null;
        try {
            engine.eval(js);
            if (engine instanceof Invocable) {
                Invocable inv = (Invocable) engine;
                value = String.valueOf(inv.invokeFunction(functionName));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }


    /**
     * 
     *
     * @param js js代码
     * @param functionName js方法名称
     * @param functionParams js参数
     * @return 调用js的返回值
     */
    public String script(String js, String functionName, Object[] functionParams) {
        if (functionParams == null 
                && js != null 
                && functionName != null) { //无参数
            return this.runScript(js, functionName);
        } else if (functionParams != null 
                && js != null 
                && functionName != null) { //一个参数
            return this.runScript(js, functionName, functionParams);
        } else if (js != null) { //只有js代码
            return this.runScriptS(js);
        }
        return null;
    }


}

推荐阅读