美文网首页
JAVA使用脚本引擎执行JS代码

JAVA使用脚本引擎执行JS代码

作者: 林零呓 | 来源:发表于2018-11-12 00:04 被阅读66次

    在开发过程中我们可能需要通过Java来调用执行JavaScript脚本,比如我们在用Java做网络爬虫时,有时需要执行JS代码来对一些请求的参数进行加密。下面简单介绍一下如何用Java执行JS脚本代码。

    简单的使用:

    package com.my.js;
    
    import javax.script.Invocable;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    
    public class First {
        /**
         * 
         * @param jsStr js脚本内容
         * @param function  要调用的js方法名
         * @param args  调用js方法时传入的参数
         * @return
         */
        public static Object jsObjFunc(String jsStr,String function,Object... args) {
            ScriptEngineManager sem = new ScriptEngineManager();
            ScriptEngine scriptEngine = sem.getEngineByName("js");
            try {
                scriptEngine.eval(jsStr);
                Invocable inv2 = (Invocable) scriptEngine;
                return  inv2.invokeFunction(function,args);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        public static void main(String[] args)throws Exception {
            String jsStr ="function myFuc(param){return \"the param is:\"+param;}";//js脚本内容
            System.out.println(jsObjFunc(jsStr,"myFuc","test"));
        }
    }
    

    针对多次调用的优化,并进行简单的封装后:

    package com.my.js;
    
    import javax.script.*;
    import java.util.Map;
    
    public class ScriptCompile {
        CompiledScript script;
        ScriptEngine engine ;
        ScriptCompile(String scriptText){
            this.script =initScript(scriptText,null);
        }
        /**
         *
         * @param scriptText    js脚本内容
         * @param initParams    在编译时, 初始化时传入脚本的参数
         */
        ScriptCompile(String scriptText,Map<String,Object> initParams){   //构造函数, 先编译
            this.script =initScript(scriptText,initParams);
        }
        public CompiledScript initScript(String scriptText,Map<String,Object> initParams){
            CompiledScript script =null;
            ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
            if(initParams!=null&&!initParams.isEmpty()) {
                for (Map.Entry<String, Object> entry : initParams.entrySet()) {
                    engine.put(entry.getKey(), entry.getValue());
                }
            }
            this.engine= engine;
            if (engine instanceof Compilable) {
                try {
                    script = ((Compilable) engine).compile(scriptText);
                } catch (ScriptException e) {
                    e.printStackTrace();
                }
            }
            return script;
        }
    
        /**
         * 执行脚本
         * @param bindingsMap   本次执行时传入的参数
         * @return
         * @throws ScriptException
         */
        public Object execute(Map<String,Object> bindingsMap) throws ScriptException {
            if(bindingsMap!=null&&!bindingsMap.isEmpty()){
                Bindings bindings = new SimpleBindings();
                for(Map.Entry<String,Object> entry: bindingsMap.entrySet()){
                    bindings.put(entry.getKey(),entry.getValue());
                }
                return script.eval(bindings);
            }else{
                return script.eval();
            }
        }
        public Object execute() throws ScriptException {
            return execute(null);
        }
    
        /**
         * 调用脚本中的某个函数
         * @param bindingsMap   本次执行传入的参数
         * @param fucName  函数名
         * @param args  函数参数,可以有多个参数
         * @return
         * @throws Exception
         */
        public Object executeFuc(Map<String,Object> bindingsMap,String fucName,Object...args) throws Exception {
            execute(bindingsMap);
            Invocable inv2 = (Invocable) engine;
            return  inv2.invokeFunction(fucName,args);
        }
        public Object executeFuc(String fucName,Object...args) throws Exception {
            return executeFuc(null,fucName,args);
        }
    }
    
    

    调用:

        public static void main(String[] args) {
            Map<String,Object> map=new HashMap<>();
            map.put("counter",9);
            ScriptCompile sc = new ScriptCompile(
                    "function count(num) {counter = counter +num; " +
                    " return counter; }; " +
    //                "count();" +
                    "",map);
    
            for(int i=0;i<5;i++) {
                try {
    //                map.put("counter",9);   //本次执行 要传递的参数
    //                System.out.println(sc.run());
                    System.out.println(sc.executeFuc("count",2));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    

    执行结果:
    11.0
    13.0
    15.0
    17.0
    19.0

    相关文章

      网友评论

          本文标题:JAVA使用脚本引擎执行JS代码

          本文链接:https://www.haomeiwen.com/subject/ikoffqtx.html