????? 在我们开发的过程中,可能有这么一种情况,在java中需要取调用js方法完成一些事情。那么什么时候可能出现这种情况呢。比如我们使用爬虫模拟登录别的网站,但有些网站前台使用js对密码进行了加密处理,那么就需要在java中进行调用js方法,完成js密码的加密操作。
在这篇博客记录如下几种调用方式:
1、java执行js文件
2、js方法写在java代码中,然后执行
4、在js中调用java类
?
实现:
1、java执行js文件
???? |- 执行js文件中的方法
???? |- 向js方法中传递参数
???? |- 获取到js方法执行后的返回值
1.1 js方法的定义
class="js">function showUser(name) { // console.info("haha"); return "haha[" + name + "],我返回了值"; }
?
?1.2 java代码
@Test public void invokedJsFile() throws Exception { try (InputStream is = JavaInvokeJsTest.class.getResourceAsStream("script.js")) { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); // 拿到js脚本引擎 ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("js"); InputStreamReader isr = new InputStreamReader(is); scriptEngine.eval(isr); if (scriptEngine instanceof Invocable) { Invocable invocable = (Invocable) scriptEngine; /** * 调用showUser方法,javascript engine 作为参数传入showUser方法中 */ String result = (String) invocable.invokeFunction("showUser", "javascript engine"); System.out.println("the result is : " + result); } } }
?1.3 结果
?
2、js方法写在java代码中
2.1 java代码
@Test public void invokedScriptMethod() throws Exception { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("js"); scriptEngine.put("userName", "张三"); String script = "function showName(flag){ if(flag){ return userName + ',你好.' ;} else { return '不满足条件';} }"; scriptEngine.eval(script); Invocable invocable = (Invocable) scriptEngine; String result = (String) invocable.invokeFunction("showName", true); System.out.println(result); }
?2.2结果
3.脚本引擎自身的作用域和全局作用域
?? |- ScriptEngineManager的put方法设置全局作用域
?? |- ScriptEngine的put设置脚本自身的作用域
@Test public void testScriptScope() throws Exception { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine1 = scriptEngineManager.getEngineByName("js"); // 向脚本的全局作用域中设置值 scriptEngineManager.put("globalVal", "全局"); // 此值时脚本自身的作用域 scriptEngine1.put("userName", "张三"); String script1 = "function showName(){ return '获取全局作用域globalVal的值:['+globalVal + ']: 获取自身作用域username的值:[' + userName + '].' ; }"; scriptEngine1.eval(script1); Invocable invocable1 = (Invocable) scriptEngine1; String result1 = (String) invocable1.invokeFunction("showName"); System.out.println(result1); ScriptEngine scriptEngine2 = scriptEngineManager.getEngineByName("js"); scriptEngine2.put("userName", "李四"); String script2 = "function showName(){ return '获取全局作用域globalVal的值:['+globalVal + ']: 获取自身作用域username的值:[' + userName + '].' ; }"; scriptEngine2.eval(script2); Invocable invocable2 = (Invocable) scriptEngine2; String result2 = (String) invocable2.invokeFunction("showName"); System.out.println(result2); System.out.println("====================================="); System.out.println("全局作用域的值:"); System.out.println("===> gloableVal:" + scriptEngineManager.get("globalVal")); System.out.println("脚本作用域1的值:"); System.out.println("===> userName:" + scriptEngine1.get("userName")); System.out.println("脚本作用域2的值:"); System.out.println("===> userName:" + scriptEngine2.get("userName")); System.out.println("====================================="); }
?结果:
?
4、在js中调用java类
?? |- 实现效果,js中将java的list集合中的元素改变,并加上一个new java.util.Date()的值
?4.1 Java代码
??? |- String script 中写出了js中如何调用java方法。
@Test public void testJava() throws Exception { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("js"); List<String> list = new ArrayList<>(3); list.add("张三"); list.add("李四"); list.add("wangwu"); String script = "function show(list){ for(var i=0;i<list.size();i++){ list.set(i,list.get(i)+':'+i); };list.add(new java.util.Date().toString());}"; scriptEngine.eval(script); Invocable invocable = (Invocable) scriptEngine; invocable.invokeFunction("show", list); System.out.println(list); }
?4.2 结果
?
????? 一般情况下,在java中调用js方法的情况少,不过了解一下也是有好处的。
?
?
?
?
?
?
?
?
?
?