標籤:
http://blog.csdn.net/xzyxuanyuan/article/details/8062887
JDK1.6版添加了新的ScriptEngine類,允許使用者直接執行js代碼。
在Java中直接調用js代碼
不能呼叫瀏覽器中定義的js函數,會拋出異常提示ReferenceError: “alert” is not defined。
| |
package com.sinaapp.manjushri; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; /** * 直接調用js代碼 */ public class ScriptEngineTest { public static void main(String[] args) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); try{ engine.eval("var a=3; var b=4;print (a+b);"); // engine.eval("alert(\"js alert\");"); // 不能呼叫瀏覽器中定義的js函數 // 錯誤,會拋出alert引用不存在的異常 }catch(ScriptException e){ e.printStackTrace(); } } } |
輸出結果:7
在Java中綁定js變數
在調用engine.get(key);時,如果key沒有定義,則返回null
| |
package com.sinaapp.manjushri; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class ScriptEngineTest2 { public static void main(String[] args) { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.put("a", 4); engine.put("b", 3); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); try { // 只能為Double,使用Float和Integer會拋出異常 Double result = (Double) engine.eval("a+b"); System.out.println("result = " + result); engine.eval("c=a+b"); Double c = (Double)engine.get("c"); System.out.println("c = " + c); } catch (ScriptException e) { e.printStackTrace(); } } } |
輸出:
result = 7.0
c = 7.0
在Java中調用js檔案中的function,傳入調用參數,並擷取傳回值
js檔案中的merge函數將兩個參數a,b相加,並返回c。
| |
// expression.js function merge(a, b) { c = a * b; return c; } |
在Java代碼中讀取js檔案,並參數兩個參數,然後回去傳回值。
| |
package com.sinaapp.manjushri; import java.io.FileReader; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; /** * Java調用並執行js檔案,傳遞參數,並活動傳回值 * * @author manjushri */ public class ScriptEngineTest { public static void main(String[] args) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); String jsFileName = "expression.js"; // 讀取js檔案 FileReader reader = new FileReader(jsFileName); // 執行指定指令碼 engine.eval(reader); if(engine instanceof Invocable) { Invocable invoke = (Invocable)engine; // 調用merge方法,並傳入兩個參數 // c = merge(2, 3); Double c = (Double)invoke.invokeFunction("merge", 2, 3); System.out.println("c = " + c); } reader.close(); }} |
輸出結果:
c = 5.0
java呼叫指令碼語言筆記(jython,jruby,groovy)
有兩種方法
1.java se 6以後實現了jsr 223規範
java代碼:
[java]
- ScriptEngineManager factory = new ScriptEngineManager();
- ScriptEngineManager scriptEngine = factory.getEngineByName("javascript");//或者"js"
- scriptEngine.eval(code);//執行一段指令碼,code是js代碼
很方便呼叫指令碼
2.可以使用指令碼語方本身提供的與java的整合手段
jython整合
使用jsr223:
前提下載jython的包,已實現jsr223
(建議在官網上下載,在安裝目錄下有jython.jar,http://repo2.maven.org/maven2/org/python/jython/2.5.0/ 這裡也有,但是這個包裡沒有jsr223的實現,看包下存不存在org.python.jsr223)
[java]
- ScriptEngineManager factory = new ScriptEngineManager();
- ScriptEngineManager scriptEngine = factory.getEngineByName("python");//或者"jython"
- scriptEngine.eval(code);
使用PythonInterpreter,可以調用exec(String code)方法:
[java]
- PythonInterpreter interpreter = new PythonInterpreter();
- interpreter.exec(code);
訪問資料庫
使用jdbc:
[python]
- from oracle.jdbc.driver import OracleDriver
- from java.sql import DriverManager
-
- username = ‘hr‘
- password = ‘123456‘
- url = ‘jdbc:oracle:thin:@localhost:1521:XE‘
- driver = OracleDriver()
- DriverManager.registerDriver(driver)
- conn = DriverManager.getConnection(url, username, password)
- stmt = conn.createStatement()
- sql = "select salary from EMPLOYEES t where t.salary<2300"
- rs = stmt.executeQuery(sql)
- while (rs.next()):
- print rs.getInt(‘salary‘)
- rs.close()
- stmt.close()
結果:
2200
2100
2200
使用zxJDBC :
[python]
- from com.ziclix.python.sql import zxJDBC
-
- url = ‘jdbc:oracle:thin:@localhost:1521:XE‘
- username = ‘hr‘
- password = ‘123456‘
- driverName = ‘oracle.jdbc.driver.OracleDriver‘
- mysqlConn = zxJDBC.connect(url,username, password,driverName)
- cursor = mysqlConn.cursor()
- cursor.execute("select last_name from EMPLOYEES t where t.salary<2300");
- #print cursor.fetchone()
- list = cursor.fetchall()
- for record in list:
- print "name:"+record[0]
- #print cursor.description[0]
- #print cursor.description[1]
結果:
name:麥克
name:Olson
name:Philtanker
從資料庫中查出的中文內容正常的。
而在代碼裡面的中文全部是亂碼或拋異常,未解決。
與jruby整合
使用jsr223:Java代碼
[java]
- ScriptEngineManager factory = new ScriptEngineManager();
- ScriptEngineManager scriptEngine = factory.getEngineByName("jruby");//或者"ruby"
- scriptEngine.eval(code);
訪問資料庫
Ruby代碼
[ruby]
- require ‘java‘
-
- module JavaLang
- include_package "java.lang"
- end
-
- module JavaSql
- include_package ‘java.sql‘
- end
-
- begin
- username = ‘hr‘
- password = ‘123456‘
- url = ‘jdbc:oracle:thin:@localhost:1521:XE‘
- driverName = ‘oracle.jdbc.driver.OracleDriver‘
- JavaLang::Class.forName(driverName).newInstance
- conn = JavaSql::DriverManager.getConnection(url, username, password)
- stmt = conn.createStatement
- sql = "select last_name from EMPLOYEES t where t.salary<2300"
- rs = stmt.executeQuery(sql)
- while (rs.next) do
- puts "名字:"+rs.getString("last_name")
- end
- rs.close
- stmt.close
- conn.close()
- rescue JavaLang::ClassNotFoundException
- puts "ClassNotFoundException"
- rescue JavaSql::SQLException
- puts "SQLException"
- end
結果:
名字:楹﹀厠
名字:Olson
名字:Philtanker
從資料庫中查出的中文內容為亂碼的。
而在代碼裡面的中文正常。
與groovy整合
使用jsr223:
Java代碼
[java]
- ScriptEngineManager factory = new ScriptEngineManager();
- ScriptEngineManager scriptEngine = factory.getEngineByName("groovy");//或者"Groovy"
- scriptEngine.eval(code);
使用GroovyShell:
Java代碼
[java]
- GroovyShell shell = new GroovyShell();
- Script script = shell.parse(code);
- Object result = script.run();
訪問資料庫
Groovy代碼
- import groovy.sql.Sql
-
- def username = ‘hr‘
- def password = ‘123456‘
- def url = ‘jdbc:oracle:thin:@localhost:1521:XE‘
- def driverName = ‘oracle.jdbc.driver.OracleDriver‘
- def sql = Sql.newInstance(url, username, password, driverName)
-
- sql.eachRow("select last_name from EMPLOYEES t where t.salary<2300") {
- println "名字:${it.last_name}"
- }
結果:
名字:麥克
名字:Olson
名字:Philtanker
在使用groovy過程中碰到了一個異常
Exception in thread "main" java.lang.VerifyError: (class: groovy/runtime/metaclass/java/util/ArrayListMetaClass, method: super$2$invokeMethod signature: (Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;ZZ)Ljava/lang/Object;) Illegal use of nonvirtual function call
這個異常解決花了很長時間
是因為在原來項目中存在json-lib-2.1.jar(有可能名稱為json-lib-2.1-jdk15.jar),這個包是用來處理json的,與groovy1.7.5存在衝突,更新為json-lib-2.3.jar即可
(json-lib裡有一些groovy運行時處理的內容)
在Java中直接調用js代碼(轉載)